2013-09-26 15 views

Odpowiedz

11

Jest to możliwe za pomocą kilku prostych hacków na prototypie Bone i Object3D. Ponieważ kości dziedziczą z Object3D, mogą mieć dzieci, więc możemy łatwo .add() a mesh do dowolnej kości.

Jednak SkinnedMesh wywoła tylko updateMatrixWorld() na dzieciach innych niż Bone i update() dla dzieci Bone. Dodatkowo, kości wywołują update() dla każdego z jego dzieci (bez względu na to, czy jest to kość, czy nie). Poniższe fragmenty kodu zmieniają to zachowanie:

// modify bone update function to also update its world matrix 
// possibly do this only to skeletons you need it for, not for all bones 
var update = THREE.Bone.prototype.update; 
THREE.Bone.prototype.update = function(parentSkinMatrix, forceUpdate) { 
    update.call(this, parentSkinMatrix, forceUpdate); 
    this.updateMatrixWorld(true); 
}; 

// add noop update function to Object3D prototype 
// so any Object3D may be a child of a Bone 
THREE.Object3D.prototype.update = function() {}; 

// create buffalo ... 

// create a mesh and add it to some bone 
var mesh = new THREE.Mesh(new THREE.SphereGeometry(20), new THREE.MeshNormalMaterial()); 

var bone = buffalo.bones[5]; 
bone.add(mesh); 
+3

wow. taka odpowiedź. bardzo pomocny. bardzo dziękuję. łał. – Gugis

8

Three.js Wersja 68 obsługuje to po wyjęciu z pudełka, ale nieco inaczej. Nie jest konieczna zmiana wewnętrznych funkcji.

Teraz działa tak:

hierarchii kości jest teraz znaleźć u dzieci z SkinnedMesh.

Znajdź kość na liście dzieci i po prostu dołączyć obiekt do niego:

player.children[0].add(testObj); 

Uwaga: Jeśli masz hierarchię kości (na przykład w eksportowanego modelu blendera), to jest reprezentowana w trzech. js też. Jeśli docelowa kość ma kość rodzicielską, będzie wyglądać następująco:

player.children[0].children[1].add(testObj);