シーン内の2つのオブジェクト。キューブ回転軸はキューブの中心である必要があります、それは私の期待です。
しかし、靴モデルの回転軸は世界のy軸です。
私の元のコードは。
cube.rotation.y += 0.01;
shoe.rotation.y += 0.01;
次のように、stackoverflowで解決策を見つけました。
cube.rotation.y += 0.01;
var pivot = new THREE.Object3D();
pivot.add(shoe);
pivot.rotation.y += 0.01;
しかし、それは機能しません。そして、靴の位置を変更します。
cube.rotation.y += 0.01;
var pivot = new THREE.Object3D();
shoe.position.set(-5,0,0);
pivot.add(shoe);
pivot.rotation.y += 0.01;
結果は改善されましたが、まだ完全ではありません。靴のモデルはたくさんあるので、靴のモデルごとに異なる位置を決定することはできません。
メッシュがその中心の周りを回転していない場合、ジオメトリの頂点が原点からオフセットされているためです。
バウンディングボックスを使用して適切な中心を定義し、メッシュの位置を次のようにオフセットすることにより、再配置を自動化できます。
var box = new THREE.Box3().setFromObject( mesh );
box.center( mesh.position ); // this re-sets the mesh position
mesh.position.multiplyScalar( - 1 );
次に、メッシュをピボットオブジェクトに追加します。
var pivot = new THREE.Group();
scene.add( pivot );
pivot.add( mesh );
アニメーションループで、ピボットを回転させます。
pivot.rotation.y += 0.01;
編集: 別の解決策 は、ジオメトリの頂点を変換して、ジオメトリが原点の中心またはその近くにくるようにします。
geometry.translate( distX, distY, distZ );
または、代わりに、単に呼び出すことができます:
geometry.center();
ジオメトリの境界ボックスに基づいて、ジオメトリの頂点を中央に配置します。
three.js r.97
THREE.Geometry.prototype.centerを次のように使用します。
myGeometry.center();
これは、myGeometery.translate(x、y、z)と自動センタリング(x、y、z)を使用するようなものです。
ピボットソリューションはうまくいきませんでした。
OBJLoader.js(.objオブジェクトの読み込み用)では、オブジェクトのboundingBoxを取得し、その中心を取得し、スカラーに-1を乗算し、これを使用してすべての子のジオメトリのジオメトリを変換する必要があります。次に、目的に使用する場合は、boundingBoxを再更新する必要があります。
以下は、OBJおよびMTL(テクスチャ)ファイルのディレクトリと名前を指定して、objをロードし、ジオメトリ頂点を「正規化」する関数です(たとえば、OBJおよびMTLファイルがdir1/myObject.objおよびdir1/myObjectである場合) .mtl、次にloadObj( 'dir1'、 'myObject'))を呼び出します。
function loadObj(dir, objName) {
var onProgress = function(xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}
};
var onError = function(xhr) {};
// Manager
var manager = new THREE.LoadingManager();
manager.onProgress = function(item, loaded, total) {
console.log( 'Started loading file: ' + item + '.\nLoaded ' + loaded + ' of ' + total + ' files.' );
};
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath(dir);
mtlLoader.load(objName + '.mtl', function(materials) {
materials.preload();
// Model
var loader = new THREE.OBJLoader(manager);
loader.setMaterials(materials);
loader.setPath(dir);
loader.load(objName + '.obj', function (object) {
var objBbox = new THREE.Box3().setFromObject(object);
// Geometry vertices centering to world axis
var bboxCenter = objBbox.getCenter().clone();
bboxCenter.multiplyScalar(-1);
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.geometry.translate(bboxCenter.x, bboxCenter.y, bboxCenter.z);
}
});
objBbox.setFromObject(object); // Update the bounding box
scene.add(object);
}, onProgress, onError);
});
}
私がr86で動作するようになった方法
// Store original position
let box = new THREE.Box3().setFromObject(this.mesh);
let offset = box.getCenter();
// Center geometry faces
this.geometry.center();
// Add to pivot group
this.group = new THREE.Object3D();
this.group.add(this.mesh);
// Offset pivot group by original position
this.group.position.set(offset.x, offset.y, offset.z);