Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js:更改精灵的轴心点_Three.js - Fatal编程技术网

Three.js:更改精灵的轴心点

Three.js:更改精灵的轴心点,three.js,Three.js,我已经创建了一个3D地图,并通过精灵在地图上标记点。这本身就可以很好地工作,除了精灵标签的定位 因为我正在创建一张地图,相机可以从0度倾斜到90度,而理想情况下,标签始终保持在屏幕上它正在标记的项目的正上方一段距离。但不幸的是,由于精灵始终围绕其原点居中,并且与项目重叠,我必须在Y世界轴上向上移动精灵,并且随着相机倾斜,精灵的中心位置会发生变化。如果被观察的物体偏离中心,这看起来很奇怪,而且当相机直视时,效果不太好 手边没有JSFIDLE,但我在的应用程序应该会给人一个很好的印象 SpriteP

我已经创建了一个3D地图,并通过精灵在地图上标记点。这本身就可以很好地工作,除了精灵标签的定位

因为我正在创建一张地图,相机可以从0度倾斜到90度,而理想情况下,标签始终保持在屏幕上它正在标记的项目的正上方一段距离。但不幸的是,由于精灵始终围绕其原点居中,并且与项目重叠,我必须在Y世界轴上向上移动精灵,并且随着相机倾斜,精灵的中心位置会发生变化。如果被观察的物体偏离中心,这看起来很奇怪,而且当相机直视时,效果不太好

手边没有JSFIDLE,但我在的应用程序应该会给人一个很好的印象

SpritePlugin的代码向我建议,在渲染时,应该可以使用“matrixWorld”将精灵在屏幕Y轴上向上移动一段距离,但我不知道如何使用它,也不完全确定这是我首先需要使用的

渲染时是否可以在屏幕上向上移动精灵,或者更改其原点?或者有没有其他方法可以达到同样的效果


Three.js r.67

正如WestLangley所建议的那样,我已经创建了一个可行的解决方案,根据观察角度改变精灵的位置,尽管我花了几个小时来计算出数学运算所需的几行代码。我也更新了我的应用程序,所以请看现场演示

使用从
OrbitControls.js
中的相机计算的倾斜角度
phi
和航向角度
theta
,以下代码计算精灵偏移量,该偏移量完全符合我的要求:

// Given:
// phi = tilt; 0 = top down view, 1.48 = 85 degrees (almost head on)
// theta = heading; 0 = north, < 0 looking east, > 0 looking west

// Compute an "opposite" angle; note the 'YXZ' axis order is important
var euler = new THREE.Euler( phi + Math.PI / 2, theta, 0, 'YXZ' );
// Labels are positioned 5.5 units up the Y axis relative to its parent
var spriteOffset = new THREE.Vector3( 0, -5.5, 0 );
// Rotate the offset vector to be opposite to the camera
spriteOffset.applyMatrix4( new THREE.Matrix4().makeRotationFromEuler( euler ) );

scene.traverse( function ( object ) {
   if ( ( object instanceof THREE.Sprite ) && object.userData.isLabel ) {
      object.position.copy( spriteOffset );
   }
} );
//给定:
//φ=倾斜;0=自顶向下视图,1.48=85度(几乎迎面)
//θ=航向;0=北,<0向东看,>0向西看
//计算一个“相反”的角度;注意“YXZ”轴顺序很重要
var euler=新的三个.euler(φ+Math.PI/2,θ,0,'YXZ');
//标签相对于其父项沿Y轴向上放置5.5个单位
var spriteOffset=新的三个向量3(0,-5.5,0);
//旋转偏移向量,使其与摄影机相对
spriteOffset.applyMatrix4(新的三个.Matrix4().makeRotationFromEuler(euler));
场景.遍历(函数(对象){
if((object instanceof THREE.Sprite)和&object.userData.isLabel){
对象。位置。复制(spriteOffset);
}
} );

请注意,使用此代码的人:精灵标签是他们所指对象组的子对象,这仅设置与父对象的局部偏移。

我也有类似的问题,但使用平面精灵;我把树放在地图上,希望它们能以这样一种方式旋转,即它们能绕着底部旋转,而不是围绕中心旋转。为此,我只需将树的图像文件编辑为两倍高,底部仅为透明度:

如果将第一个图像转化为精灵,当摄影机旋转时,它将围绕树的中心旋转。当摄影机旋转时,第二棵树将围绕其底部旋转


对于您的应用程序,如果您调整文本框的大小,使其中心与星形重合;也许通过添加一些换行符或编辑精灵的高度,这是一个非常棘手的问题,但如果您仅以这种方式使用精灵,并且能够容忍精灵呈现方式的全局更改,则可以在编译的
three.js
脚本中更改以下行:

找到(ctrl+F)
THREE.SpritePlugin=function
,您将看到:

this.init = function ( renderer ) {

    _gl = renderer.context;
    _renderer = renderer;

    vertices = new Float32Array( [
        - 0.5, - 0.5, 0, 0, 
          0.5, - 0.5, 1, 0,
          0.5,   0.5, 1, 1,
        - 0.5,   0.5, 0, 1
    ] );
我将数组的定义更改为以下内容:

    var vertices = new Float32Array( [
        - 0.5, - 0.0,  0, 0,
          0.5, - 0.0,  1, 0,
          0.5,   1.0,  1, 1,
        - 0.5,   1.0,  0, 1 
    ] );
现在,我所有的精灵都以底部的旋转原点进行渲染

如果使用缩小版本,请搜索
THREE.SpritePlugin=function
,然后向右移动光标,直到找到定义的Float32Array,并在那里进行相同的更改

注意:这只会更改使用WebGL时的渲染方式。对于画布渲染器,您必须在
THREE.CanvasRenderer
中播放名为
renderSprite()
的函数。我怀疑玩这些台词可以做到:

var dist = 0.5 * Math.sqrt( scaleX * scaleX + scaleY * scaleY ); // allow for rotated sprite
_elemBox.min.set( v1.x - dist, v1.y - dist );
_elemBox.max.set( v1.x + dist, v1.y + dist );
这个函数在缩小版中也很难找到,因为
renderSprite()
不是一个朝外的函数,它可能会被重命名为一个模糊的小函数

注2:我确实尝试过使用“polyfills”进行这些修改(或者更确切地说,在定义了三个之后重新定义SpritePlugin),但由于某些原因,它导致了一些无法正确定义的问题。范围界定也是“polyfill”方法的一个问题


注3:我的three.js版本是r69。因此,上面可能存在差异。

three.js r.67不支持更改精灵的原点。可以根据摄影机的视角移动精灵的位置。您也可以像中一样使用
正交摄影机在第二遍渲染精灵,但您现在拥有的可能更好。three.js是否有增强功能,可以让您的生活更轻松?非常好的演示,顺便说一句。谢谢:)。。。我想不出有什么特别的增强可以让使用three.js更容易。数学很难(无论如何对我来说),而把如何调用的东西组合起来让它工作有时相当困难。我们可以找到一些关于如何做某些事情的信息,但是它们到处都是。如果有可能在three.js内核中做一些类似于我答案中的片段的事情,那么我想有这样一种改变精灵起源的方法可能对一些人有用。我当然考虑过这一点,但由于我目前需要107个具有相当高细节的独特纹理(文本渲染到画布上),并且它们是动态生成的,这将增加大量内存