Skip to content

Commit f21ecaf

Browse files
committed
BufferGeometryUtils: Fixed computeMorphedBufferGeometry()
1 parent 2591284 commit f21ecaf

File tree

2 files changed

+324
-12
lines changed

2 files changed

+324
-12
lines changed

examples/js/utils/BufferGeometryUtils.js

Lines changed: 312 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -744,7 +744,6 @@ THREE.BufferGeometryUtils = {
744744
newIndices.push( index.getX( i + 1 ) );
745745
newIndices.push( index.getX( i + 2 ) );
746746

747-
748747
} else {
749748

750749
newIndices.push( index.getX( i + 2 ) );
@@ -778,6 +777,318 @@ THREE.BufferGeometryUtils = {
778777

779778
}
780779

780+
},
781+
782+
/**
783+
* Calculates the morphed attributes of a morphed/skinned BufferGeometry.
784+
* Helpful for Raytracing or Decals.
785+
* @param {Object3D} object
786+
* @return {Object} An Object with original position/normal attributes and morphed ones.
787+
*/
788+
computeMorphedBufferGeometry: function ( object ) {
789+
790+
if ( ! object ) {
791+
792+
console.error( 'Please provide an object' );
793+
return null;
794+
795+
}
796+
797+
if ( ! object.geometry ) {
798+
799+
console.error( 'Please provide an object with a geometry' );
800+
return null;
801+
802+
}
803+
804+
if ( ! object.geometry.isBufferGeometry ) {
805+
806+
console.error( 'Geometry is not a BufferGeometry' );
807+
return null;
808+
809+
}
810+
811+
var _vA = new THREE.Vector3();
812+
var _vB = new THREE.Vector3();
813+
var _vC = new THREE.Vector3();
814+
815+
var _tempA = new THREE.Vector3();
816+
var _tempB = new THREE.Vector3();
817+
var _tempC = new THREE.Vector3();
818+
819+
var _morphA = new THREE.Vector3();
820+
var _morphB = new THREE.Vector3();
821+
var _morphC = new THREE.Vector3();
822+
823+
function _calculateMorphedAttributeData(
824+
object,
825+
material,
826+
attribute,
827+
morphAttribute,
828+
morphTargetsRelative,
829+
a,
830+
b,
831+
c,
832+
modifiedAttributeArray
833+
) {
834+
835+
_vA.fromBufferAttribute( attribute, a );
836+
_vB.fromBufferAttribute( attribute, b );
837+
_vC.fromBufferAttribute( attribute, c );
838+
839+
var morphInfluences = object.morphTargetInfluences;
840+
841+
if ( material.morphTargets && morphAttribute && morphInfluences ) {
842+
843+
_morphA.set( 0, 0, 0 );
844+
_morphB.set( 0, 0, 0 );
845+
_morphC.set( 0, 0, 0 );
846+
847+
for ( var i = 0, il = morphAttribute.length; i < il; i ++ ) {
848+
849+
var influence = morphInfluences[ i ];
850+
var morphAttribute = morphAttribute[ i ];
851+
852+
if ( influence === 0 ) continue;
853+
854+
_tempA.fromBufferAttribute( morphAttribute, a );
855+
_tempB.fromBufferAttribute( morphAttribute, b );
856+
_tempC.fromBufferAttribute( morphAttribute, c );
857+
858+
if ( morphTargetsRelative ) {
859+
860+
_morphA.addScaledVector( _tempA, influence );
861+
_morphB.addScaledVector( _tempB, influence );
862+
_morphC.addScaledVector( _tempC, influence );
863+
864+
} else {
865+
866+
_morphA.addScaledVector( _tempA.sub( _vA ), influence );
867+
_morphB.addScaledVector( _tempB.sub( _vB ), influence );
868+
_morphC.addScaledVector( _tempC.sub( _vC ), influence );
869+
870+
}
871+
872+
}
873+
874+
_vA.add( _morphA );
875+
_vB.add( _morphB );
876+
_vC.add( _morphC );
877+
878+
}
879+
880+
if ( object.isSkinnedMesh ) {
881+
882+
object.boneTransform( a, _vA );
883+
object.boneTransform( b, _vB );
884+
object.boneTransform( c, _vC );
885+
886+
}
887+
888+
modifiedAttributeArray[ a * 3 + 0 ] = _vA.x;
889+
modifiedAttributeArray[ a * 3 + 1 ] = _vA.y;
890+
modifiedAttributeArray[ a * 3 + 2 ] = _vA.z;
891+
modifiedAttributeArray[ b * 3 + 0 ] = _vB.x;
892+
modifiedAttributeArray[ b * 3 + 1 ] = _vB.y;
893+
modifiedAttributeArray[ b * 3 + 2 ] = _vB.z;
894+
modifiedAttributeArray[ c * 3 + 0 ] = _vC.x;
895+
modifiedAttributeArray[ c * 3 + 1 ] = _vC.y;
896+
modifiedAttributeArray[ c * 3 + 2 ] = _vC.z;
897+
898+
}
899+
900+
var geometry = object.geometry;
901+
var material = object.material;
902+
903+
var a, b, c;
904+
var index = geometry.index;
905+
var positionAttribute = geometry.attributes.position;
906+
var morphPosition = geometry.morphAttributes.position;
907+
var morphTargetsRelative = geometry.morphTargetsRelative;
908+
var normalAttribute = geometry.attributes.normal;
909+
var morphNormal = geometry.morphAttributes.position;
910+
911+
var groups = geometry.groups;
912+
var drawRange = geometry.drawRange;
913+
var i, j, il, jl;
914+
var group, groupMaterial;
915+
var start, end;
916+
917+
var modifiedPosition = new Float32Array( positionAttribute.count * positionAttribute.itemSize );
918+
var modifiedNormal = new Float32Array( normalAttribute.count * normalAttribute.itemSize );
919+
920+
if ( index !== null ) {
921+
922+
// indexed buffer geometry
923+
924+
if ( Array.isArray( material ) ) {
925+
926+
for ( i = 0, il = groups.length; i < il; i ++ ) {
927+
928+
group = groups[ i ];
929+
groupMaterial = material[ group.materialIndex ];
930+
931+
start = Math.max( group.start, drawRange.start );
932+
end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
933+
934+
for ( j = start, jl = end; j < jl; j += 3 ) {
935+
936+
a = index.getX( j );
937+
b = index.getX( j + 1 );
938+
c = index.getX( j + 2 );
939+
940+
_calculateMorphedAttributeData(
941+
object,
942+
groupMaterial,
943+
positionAttribute,
944+
morphPosition,
945+
morphTargetsRelative,
946+
a, b, c,
947+
modifiedPosition
948+
);
949+
950+
_calculateMorphedAttributeData(
951+
object,
952+
groupMaterial,
953+
normalAttribute,
954+
morphNormal,
955+
morphTargetsRelative,
956+
a, b, c,
957+
modifiedNormal
958+
);
959+
960+
}
961+
962+
}
963+
964+
} else {
965+
966+
start = Math.max( 0, drawRange.start );
967+
end = Math.min( index.count, ( drawRange.start + drawRange.count ) );
968+
969+
for ( i = start, il = end; i < il; i += 3 ) {
970+
971+
a = index.getX( i );
972+
b = index.getX( i + 1 );
973+
c = index.getX( i + 2 );
974+
975+
_calculateMorphedAttributeData(
976+
object,
977+
material,
978+
positionAttribute,
979+
morphPosition,
980+
morphTargetsRelative,
981+
a, b, c,
982+
modifiedPosition
983+
);
984+
985+
_calculateMorphedAttributeData(
986+
object,
987+
material,
988+
normalAttribute,
989+
morphNormal,
990+
morphTargetsRelative,
991+
a, b, c,
992+
modifiedNormal
993+
);
994+
995+
}
996+
997+
}
998+
999+
} else if ( positionAttribute !== undefined ) {
1000+
1001+
// non-indexed buffer geometry
1002+
1003+
if ( Array.isArray( material ) ) {
1004+
1005+
for ( i = 0, il = groups.length; i < il; i ++ ) {
1006+
1007+
group = groups[ i ];
1008+
groupMaterial = material[ group.materialIndex ];
1009+
1010+
start = Math.max( group.start, drawRange.start );
1011+
end = Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) );
1012+
1013+
for ( j = start, jl = end; j < jl; j += 3 ) {
1014+
1015+
a = j;
1016+
b = j + 1;
1017+
c = j + 2;
1018+
1019+
_calculateMorphedAttributeData(
1020+
object,
1021+
groupMaterial,
1022+
positionAttribute,
1023+
morphPosition,
1024+
morphTargetsRelative,
1025+
a, b, c,
1026+
modifiedPosition
1027+
);
1028+
1029+
_calculateMorphedAttributeData(
1030+
object,
1031+
groupMaterial,
1032+
normalAttribute,
1033+
morphNormal,
1034+
morphTargetsRelative,
1035+
a, b, c,
1036+
modifiedNormal
1037+
);
1038+
1039+
}
1040+
1041+
}
1042+
1043+
} else {
1044+
1045+
start = Math.max( 0, drawRange.start );
1046+
end = Math.min( positionAttribute.count, ( drawRange.start + drawRange.count ) );
1047+
1048+
for ( i = start, il = end; i < il; i += 3 ) {
1049+
1050+
a = i;
1051+
b = i + 1;
1052+
c = i + 2;
1053+
1054+
_calculateMorphedAttributeData(
1055+
object,
1056+
material,
1057+
positionAttribute,
1058+
morphPosition,
1059+
morphTargetsRelative,
1060+
a, b, c,
1061+
modifiedPosition
1062+
);
1063+
1064+
_calculateMorphedAttributeData(
1065+
object,
1066+
material,
1067+
normalAttribute,
1068+
morphNormal,
1069+
morphTargetsRelative,
1070+
a, b, c,
1071+
modifiedNormal
1072+
);
1073+
1074+
}
1075+
1076+
}
1077+
1078+
}
1079+
1080+
var morphedPositionAttribute = new THREE.Float32BufferAttribute( modifiedPosition, 3 );
1081+
var morphedNormalAttribute = new THREE.Float32BufferAttribute( modifiedNormal, 3 );
1082+
1083+
return {
1084+
1085+
positionAttribute: positionAttribute,
1086+
normalAttribute: normalAttribute,
1087+
morphedPositionAttribute: morphedPositionAttribute,
1088+
morphedNormalAttribute: morphedNormalAttribute
1089+
1090+
};
1091+
7811092
}
7821093

7831094
};

examples/jsm/utils/BufferGeometryUtils.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
BufferAttribute,
33
BufferGeometry,
4+
Float32BufferAttribute,
45
InterleavedBuffer,
56
InterleavedBufferAttribute,
67
TriangleFanDrawMode,
@@ -820,17 +821,17 @@ var BufferGeometryUtils = {
820821

821822
}
822823

823-
var _vA = new THREE.Vector3();
824-
var _vB = new THREE.Vector3();
825-
var _vC = new THREE.Vector3();
824+
var _vA = new Vector3();
825+
var _vB = new Vector3();
826+
var _vC = new Vector3();
826827

827-
var _tempA = new THREE.Vector3();
828-
var _tempB = new THREE.Vector3();
829-
var _tempC = new THREE.Vector3();
828+
var _tempA = new Vector3();
829+
var _tempB = new Vector3();
830+
var _tempC = new Vector3();
830831

831-
var _morphA = new THREE.Vector3();
832-
var _morphB = new THREE.Vector3();
833-
var _morphC = new THREE.Vector3();
832+
var _morphA = new Vector3();
833+
var _morphB = new Vector3();
834+
var _morphC = new Vector3();
834835

835836
function _calculateMorphedAttributeData(
836837
object,
@@ -1089,8 +1090,8 @@ var BufferGeometryUtils = {
10891090

10901091
}
10911092

1092-
var morphedPositionAttribute = new THREE.Float32BufferAttribute( modifiedPosition, 3 );
1093-
var morphedNormalAttribute = new THREE.Float32BufferAttribute( modifiedNormal, 3 );
1093+
var morphedPositionAttribute = new Float32BufferAttribute( modifiedPosition, 3 );
1094+
var morphedNormalAttribute = new Float32BufferAttribute( modifiedNormal, 3 );
10941095

10951096
return {
10961097

0 commit comments

Comments
 (0)