@babylonjs/core 8.24.1 → 8.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Engines/abstractEngine.js +2 -2
- package/Engines/abstractEngine.js.map +1 -1
- package/Engines/engineFactory.d.ts +4 -1
- package/Engines/engineFactory.js.map +1 -1
- package/Gizmos/positionGizmo.js +3 -3
- package/Gizmos/positionGizmo.js.map +1 -1
- package/Gizmos/rotationGizmo.js +3 -3
- package/Gizmos/rotationGizmo.js.map +1 -1
- package/Gizmos/scaleGizmo.js +3 -3
- package/Gizmos/scaleGizmo.js.map +1 -1
- package/Meshes/abstractMesh.d.ts +21 -0
- package/Meshes/abstractMesh.hotSpot.js +37 -25
- package/Meshes/abstractMesh.hotSpot.js.map +1 -1
- package/Meshes/abstractMesh.js.map +1 -1
- package/Meshes/instancedMesh.d.ts +1 -0
- package/Meshes/instancedMesh.js +3 -0
- package/Meshes/instancedMesh.js.map +1 -1
- package/Meshes/mesh.d.ts +0 -19
- package/Meshes/mesh.js +0 -19
- package/Meshes/mesh.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Vector3, TmpVectors, Matrix } from "../Maths/math.vector.js";
|
|
2
2
|
import { VertexBuffer } from "../Buffers/buffer.js";
|
|
3
3
|
|
|
4
|
+
import { EnumerateFloatValues } from "../Buffers/bufferUtils.js";
|
|
4
5
|
/**
|
|
5
6
|
* Create a HotSpotQuery from a picking info
|
|
6
7
|
* @remarks If there is no pickedMesh or the pickedMesh has no indices, the faceId is used as the base index
|
|
@@ -15,6 +16,21 @@ export function CreateHotSpotQueryForPickingInfo(pickingInfo) {
|
|
|
15
16
|
barycentric: [pickingInfo.bu, pickingInfo.bv, 1 - pickingInfo.bu - pickingInfo.bv],
|
|
16
17
|
};
|
|
17
18
|
}
|
|
19
|
+
function GetVertexElementData(mesh, index, kind) {
|
|
20
|
+
const vertexBuffer = mesh.getVertexBuffer(kind);
|
|
21
|
+
if (!vertexBuffer) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const bufferData = vertexBuffer.getData();
|
|
25
|
+
if (!bufferData) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
// EnumerateFloatValues synchronously calls the callback, hence the non-null assertion.
|
|
29
|
+
let values;
|
|
30
|
+
EnumerateFloatValues(bufferData, vertexBuffer.byteStride * index, vertexBuffer.byteStride, vertexBuffer.getSize(), vertexBuffer.type, 1, // Request only a single element.
|
|
31
|
+
vertexBuffer.normalized, (v) => (values = v));
|
|
32
|
+
return values;
|
|
33
|
+
}
|
|
18
34
|
/**
|
|
19
35
|
* Return a transformed local position from a mesh and vertex index
|
|
20
36
|
* @param mesh mesh used to get vertex array from
|
|
@@ -23,63 +39,59 @@ export function CreateHotSpotQueryForPickingInfo(pickingInfo) {
|
|
|
23
39
|
* @returns false if it was not possible to compute the position for that vertex
|
|
24
40
|
*/
|
|
25
41
|
export function GetTransformedPosition(mesh, index, res) {
|
|
26
|
-
const
|
|
27
|
-
if (!
|
|
42
|
+
const positions = GetVertexElementData(mesh, index, VertexBuffer.PositionKind);
|
|
43
|
+
if (!positions) {
|
|
28
44
|
return false;
|
|
29
45
|
}
|
|
30
|
-
|
|
31
|
-
const values = [data[base + 0], data[base + 1], data[base + 2]];
|
|
32
|
-
if (values.some((value) => isNaN(value ?? Number.NaN))) {
|
|
46
|
+
if (positions.some((value) => isNaN(value ?? Number.NaN))) {
|
|
33
47
|
return false;
|
|
34
48
|
}
|
|
35
49
|
if (mesh.morphTargetManager) {
|
|
36
|
-
|
|
37
|
-
|
|
50
|
+
const base = index * 3;
|
|
51
|
+
for (let i = 0; i < positions.length; i++) {
|
|
52
|
+
let value = positions[i];
|
|
38
53
|
for (let targetCount = 0; targetCount < mesh.morphTargetManager.numTargets; targetCount++) {
|
|
39
54
|
const target = mesh.morphTargetManager.getTarget(targetCount);
|
|
40
55
|
const influence = target.influence;
|
|
41
56
|
if (influence !== 0) {
|
|
42
57
|
const targetData = target.getPositions();
|
|
43
58
|
if (targetData) {
|
|
44
|
-
value += (targetData[base +
|
|
59
|
+
value += (targetData[base + i] - positions[i]) * influence;
|
|
45
60
|
}
|
|
46
61
|
}
|
|
47
62
|
}
|
|
48
|
-
|
|
63
|
+
positions[i] = value;
|
|
49
64
|
}
|
|
50
65
|
}
|
|
51
|
-
res.fromArray(
|
|
66
|
+
res.fromArray(positions);
|
|
52
67
|
if (mesh.skeleton) {
|
|
53
|
-
const matricesIndicesData = mesh
|
|
54
|
-
const matricesWeightsData = mesh
|
|
55
|
-
if (
|
|
68
|
+
const matricesIndicesData = GetVertexElementData(mesh, index, VertexBuffer.MatricesIndicesKind);
|
|
69
|
+
const matricesWeightsData = GetVertexElementData(mesh, index, VertexBuffer.MatricesWeightsKind);
|
|
70
|
+
if (matricesIndicesData && matricesWeightsData) {
|
|
56
71
|
const needExtras = mesh.numBoneInfluencers > 4;
|
|
57
|
-
const matricesIndicesExtraData = needExtras ? mesh
|
|
58
|
-
const matricesWeightsExtraData = needExtras ? mesh
|
|
72
|
+
const matricesIndicesExtraData = needExtras ? GetVertexElementData(mesh, index, VertexBuffer.MatricesIndicesExtraKind) : null;
|
|
73
|
+
const matricesWeightsExtraData = needExtras ? GetVertexElementData(mesh, index, VertexBuffer.MatricesWeightsExtraKind) : null;
|
|
59
74
|
const skeletonMatrices = mesh.skeleton.getTransformMatrices(mesh);
|
|
60
75
|
const finalMatrix = TmpVectors.Matrix[0];
|
|
61
76
|
const tempMatrix = TmpVectors.Matrix[1];
|
|
62
77
|
finalMatrix.reset();
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
let weight;
|
|
66
|
-
for (inf = 0; inf < 4; inf++) {
|
|
67
|
-
weight = matricesWeightsData[matWeightIdx + inf];
|
|
78
|
+
for (let i = 0; i < matricesWeightsData.length; i++) {
|
|
79
|
+
const weight = matricesWeightsData[i];
|
|
68
80
|
if (weight > 0) {
|
|
69
|
-
Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[
|
|
81
|
+
Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[i] * 16), weight, tempMatrix);
|
|
70
82
|
finalMatrix.addToSelf(tempMatrix);
|
|
71
83
|
}
|
|
72
84
|
}
|
|
73
85
|
if (matricesIndicesExtraData && matricesWeightsExtraData) {
|
|
74
|
-
for (
|
|
75
|
-
weight = matricesWeightsExtraData[
|
|
86
|
+
for (let i = 0; i < matricesWeightsExtraData.length; i++) {
|
|
87
|
+
const weight = matricesWeightsExtraData[i];
|
|
76
88
|
if (weight > 0) {
|
|
77
|
-
Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData[
|
|
89
|
+
Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData[i] * 16), weight, tempMatrix);
|
|
78
90
|
finalMatrix.addToSelf(tempMatrix);
|
|
79
91
|
}
|
|
80
92
|
}
|
|
81
93
|
}
|
|
82
|
-
Vector3.TransformCoordinatesFromFloatsToRef(
|
|
94
|
+
Vector3.TransformCoordinatesFromFloatsToRef(positions[0], positions[1], positions[2], finalMatrix, res);
|
|
83
95
|
}
|
|
84
96
|
}
|
|
85
97
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"abstractMesh.hotSpot.js","sourceRoot":"","sources":["../../../../dev/core/src/Meshes/abstractMesh.hotSpot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,gCAA+B;AAgBnD;;;;;GAKG;AACH,MAAM,UAAU,gCAAgC,CAAC,WAAwB;IACrE,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,CAAC;IACrD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;IAEpC,OAAO;QACH,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC;QACxG,WAAW,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,GAAG,WAAW,CAAC,EAAE,GAAG,WAAW,CAAC,EAAE,CAAC;KACrF,CAAC;AACN,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAkB,EAAE,KAAa,EAAE,GAAY;IAClF,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IAC7D,IAAI,CAAC,IAAI,EAAE,CAAC;QACR,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC;IACvB,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;IAChE,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACrD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC1B,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC;YACjD,IAAI,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;YAC9B,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,WAAW,EAAE,EAAE,CAAC;gBACxF,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;gBAC9D,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;gBACnC,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;oBAClB,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;oBACzC,IAAI,UAAU,EAAE,CAAC;wBACb,KAAK,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,SAAS,CAAC,GAAG,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,GAAG,SAAS,CAAC;oBACjF,CAAC;gBACL,CAAC;YACL,CAAC;YACD,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;QAC9B,CAAC;IACL,CAAC;IACD,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC;QACnF,MAAM,mBAAmB,GAAG,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,mBAAmB,CAAC,CAAC;QACnF,IAAI,mBAAmB,IAAI,mBAAmB,EAAE,CAAC;YAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC;YAC/C,MAAM,wBAAwB,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjH,MAAM,wBAAwB,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjH,MAAM,gBAAgB,GAAG,IAAI,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;YAElE,MAAM,WAAW,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAExC,WAAW,CAAC,KAAK,EAAE,CAAC;YACpB,MAAM,YAAY,GAAG,KAAK,GAAG,CAAC,CAAC;YAE/B,IAAI,GAAW,CAAC;YAChB,IAAI,MAAc,CAAC;YACnB,KAAK,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;gBAC3B,MAAM,GAAG,mBAAmB,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC;gBACjD,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;oBACb,MAAM,CAAC,2BAA2B,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;oBACnI,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;gBACtC,CAAC;YACL,CAAC;YACD,IAAI,wBAAwB,IAAI,wBAAwB,EAAE,CAAC;gBACvD,KAAK,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC;oBAC3B,MAAM,GAAG,wBAAwB,CAAC,YAAY,GAAG,GAAG,CAAC,CAAC;oBACtD,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;wBACb,MAAM,CAAC,2BAA2B,CAAC,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,YAAY,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC;wBACxI,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;oBACtC,CAAC;gBACL,CAAC;YACL,CAAC;YAED,OAAO,CAAC,mCAAmC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;QACnG,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,eAAe,CAAC,IAAkB,EAAE,YAA0B,EAAE,WAAoB,EAAE,SAAmB;IACrH,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IACrF,CAAC;IAED,oCAAoC;IACpC,OAAO,CAAC,yBAAyB,CAAC,WAAW,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,WAAW,CAAC,CAAC;IAEnF,gCAAgC;IAChC,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACrC,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACvC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACjC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC1B,QAAQ,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QACjC,QAAQ,CAAC,SAAS,EAAE,CAAC;QACrB,QAAQ,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;QAElD,2CAA2C;QAC3C,MAAM,UAAU,GACZ,IAAI,CAAC,QAAQ;YACb,IAAI,CAAC,QAAQ,CAAC,eAAe;gBACzB,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC,CAAC,SAAS,CAAC,wCAAwC,CAAC,CAAC;QAElJ,IAAI,UAAU,EAAE,CAAC;YACb,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;QAED,oCAAoC;QACpC,OAAO,CAAC,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,SAAS,CAAC,CAAC;QAC1E,SAAS,CAAC,SAAS,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["import type { AbstractMesh, PickingInfo } from \"core/index\";\r\nimport { Vector3, TmpVectors, Matrix } from \"../Maths/math.vector\";\r\nimport { VertexBuffer } from \"../Buffers/buffer\";\r\nimport { Constants } from \"core/Engines/constants\";\r\n\r\n/**\r\n * Data for mesh hotspot computation\r\n */\r\nexport type HotSpotQuery = {\r\n /**\r\n * 3 point indices\r\n */\r\n pointIndex: [number, number, number];\r\n /**\r\n * 3 barycentric coordinates\r\n */\r\n barycentric: [number, number, number];\r\n};\r\n\r\n/**\r\n * Create a HotSpotQuery from a picking info\r\n * @remarks If there is no pickedMesh or the pickedMesh has no indices, the faceId is used as the base index\r\n * @param pickingInfo picking info to use\r\n * @returns the created HotSpotQuery\r\n */\r\nexport function CreateHotSpotQueryForPickingInfo(pickingInfo: PickingInfo): HotSpotQuery {\r\n const indices = pickingInfo.pickedMesh?.getIndices();\r\n const base = pickingInfo.faceId * 3;\r\n\r\n return {\r\n pointIndex: indices ? [indices[base], indices[base + 1], indices[base + 2]] : [base, base + 1, base + 2],\r\n barycentric: [pickingInfo.bu, pickingInfo.bv, 1 - pickingInfo.bu - pickingInfo.bv],\r\n };\r\n}\r\n\r\n/**\r\n * Return a transformed local position from a mesh and vertex index\r\n * @param mesh mesh used to get vertex array from\r\n * @param index vertex index\r\n * @param res resulting local position\r\n * @returns false if it was not possible to compute the position for that vertex\r\n */\r\nexport function GetTransformedPosition(mesh: AbstractMesh, index: number, res: Vector3): boolean {\r\n const data = mesh.getVerticesData(VertexBuffer.PositionKind);\r\n if (!data) {\r\n return false;\r\n }\r\n const base = index * 3;\r\n const values = [data[base + 0], data[base + 1], data[base + 2]];\r\n if (values.some((value) => isNaN(value ?? Number.NaN))) {\r\n return false;\r\n }\r\n\r\n if (mesh.morphTargetManager) {\r\n for (let component = 0; component < 3; component++) {\r\n let value = values[component];\r\n for (let targetCount = 0; targetCount < mesh.morphTargetManager.numTargets; targetCount++) {\r\n const target = mesh.morphTargetManager.getTarget(targetCount);\r\n const influence = target.influence;\r\n if (influence !== 0) {\r\n const targetData = target.getPositions();\r\n if (targetData) {\r\n value += (targetData[base + component] - data[base + component]) * influence;\r\n }\r\n }\r\n }\r\n values[component] = value;\r\n }\r\n }\r\n res.fromArray(values);\r\n if (mesh.skeleton) {\r\n const matricesIndicesData = mesh.getVerticesData(VertexBuffer.MatricesIndicesKind);\r\n const matricesWeightsData = mesh.getVerticesData(VertexBuffer.MatricesWeightsKind);\r\n if (matricesWeightsData && matricesIndicesData) {\r\n const needExtras = mesh.numBoneInfluencers > 4;\r\n const matricesIndicesExtraData = needExtras ? mesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;\r\n const matricesWeightsExtraData = needExtras ? mesh.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;\r\n const skeletonMatrices = mesh.skeleton.getTransformMatrices(mesh);\r\n\r\n const finalMatrix = TmpVectors.Matrix[0];\r\n const tempMatrix = TmpVectors.Matrix[1];\r\n\r\n finalMatrix.reset();\r\n const matWeightIdx = index * 4;\r\n\r\n let inf: number;\r\n let weight: number;\r\n for (inf = 0; inf < 4; inf++) {\r\n weight = matricesWeightsData[matWeightIdx + inf];\r\n if (weight > 0) {\r\n Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[matWeightIdx + inf] * 16), weight, tempMatrix);\r\n finalMatrix.addToSelf(tempMatrix);\r\n }\r\n }\r\n if (matricesIndicesExtraData && matricesWeightsExtraData) {\r\n for (inf = 0; inf < 4; inf++) {\r\n weight = matricesWeightsExtraData[matWeightIdx + inf];\r\n if (weight > 0) {\r\n Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData[matWeightIdx + inf] * 16), weight, tempMatrix);\r\n finalMatrix.addToSelf(tempMatrix);\r\n }\r\n }\r\n }\r\n\r\n Vector3.TransformCoordinatesFromFloatsToRef(values[0], values[1], values[2], finalMatrix, res);\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Compute a world space hotspot position\r\n * TmpVectors.Vector3[0..4] are modified by this function. Do not use them as result output.\r\n * @param mesh mesh used to get hotspot from\r\n * @param hotSpotQuery point indices and barycentric\r\n * @param resPosition output world position\r\n * @param resNormal optional output world normal\r\n * @returns false if it was not possible to compute the hotspot position\r\n */\r\nexport function GetHotSpotToRef(mesh: AbstractMesh, hotSpotQuery: HotSpotQuery, resPosition: Vector3, resNormal?: Vector3): boolean {\r\n resPosition.set(0, 0, 0);\r\n for (let i = 0; i < 3; i++) {\r\n const index = hotSpotQuery.pointIndex[i];\r\n if (!GetTransformedPosition(mesh, index, TmpVectors.Vector3[i])) {\r\n return false;\r\n }\r\n TmpVectors.Vector3[i].scaleAndAddToRef(hotSpotQuery.barycentric[i], resPosition);\r\n }\r\n\r\n // Convert the result to world space\r\n Vector3.TransformCoordinatesToRef(resPosition, mesh.getWorldMatrix(), resPosition);\r\n\r\n // compute normal in world space\r\n if (resNormal) {\r\n const pointA = TmpVectors.Vector3[0];\r\n const pointB = TmpVectors.Vector3[1];\r\n const pointC = TmpVectors.Vector3[2];\r\n const segmentA = TmpVectors.Vector3[3];\r\n const segmentB = TmpVectors.Vector3[4];\r\n segmentA.copyFrom(pointB);\r\n segmentA.subtractInPlace(pointA);\r\n segmentB.copyFrom(pointC);\r\n segmentB.subtractInPlace(pointA);\r\n segmentA.normalize();\r\n segmentB.normalize();\r\n Vector3.CrossToRef(segmentA, segmentB, resNormal);\r\n\r\n // flip normal when face culling is changed\r\n const flipNormal =\r\n mesh.material &&\r\n mesh.material.sideOrientation ===\r\n (mesh.getScene().useRightHandedSystem ? Constants.MATERIAL_ClockWiseSideOrientation : Constants.MATERIAL_CounterClockWiseSideOrientation);\r\n\r\n if (flipNormal) {\r\n resNormal.scaleInPlace(-1);\r\n }\r\n\r\n // Convert the result to world space\r\n Vector3.TransformNormalToRef(resNormal, mesh.getWorldMatrix(), resNormal);\r\n resNormal.normalize();\r\n }\r\n\r\n return true;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"abstractMesh.hotSpot.js","sourceRoot":"","sources":["../../../../dev/core/src/Meshes/abstractMesh.hotSpot.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractMesh, PickingInfo } from \"core/index\";\r\nimport { Vector3, TmpVectors, Matrix } from \"../Maths/math.vector\";\r\nimport { VertexBuffer } from \"../Buffers/buffer\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { EnumerateFloatValues } from \"core/Buffers/bufferUtils\";\r\n\r\n/**\r\n * Data for mesh hotspot computation\r\n */\r\nexport type HotSpotQuery = {\r\n /**\r\n * 3 point indices\r\n */\r\n pointIndex: [number, number, number];\r\n /**\r\n * 3 barycentric coordinates\r\n */\r\n barycentric: [number, number, number];\r\n};\r\n\r\n/**\r\n * Create a HotSpotQuery from a picking info\r\n * @remarks If there is no pickedMesh or the pickedMesh has no indices, the faceId is used as the base index\r\n * @param pickingInfo picking info to use\r\n * @returns the created HotSpotQuery\r\n */\r\nexport function CreateHotSpotQueryForPickingInfo(pickingInfo: PickingInfo): HotSpotQuery {\r\n const indices = pickingInfo.pickedMesh?.getIndices();\r\n const base = pickingInfo.faceId * 3;\r\n\r\n return {\r\n pointIndex: indices ? [indices[base], indices[base + 1], indices[base + 2]] : [base, base + 1, base + 2],\r\n barycentric: [pickingInfo.bu, pickingInfo.bv, 1 - pickingInfo.bu - pickingInfo.bv],\r\n };\r\n}\r\n\r\nfunction GetVertexElementData(mesh: AbstractMesh, index: number, kind: string) {\r\n const vertexBuffer = mesh.getVertexBuffer(kind);\r\n if (!vertexBuffer) {\r\n return null;\r\n }\r\n\r\n const bufferData = vertexBuffer.getData();\r\n if (!bufferData) {\r\n return null;\r\n }\r\n\r\n // EnumerateFloatValues synchronously calls the callback, hence the non-null assertion.\r\n let values!: number[];\r\n EnumerateFloatValues(\r\n bufferData,\r\n vertexBuffer.byteStride * index,\r\n vertexBuffer.byteStride,\r\n vertexBuffer.getSize(),\r\n vertexBuffer.type,\r\n 1, // Request only a single element.\r\n vertexBuffer.normalized,\r\n (v) => (values = v)\r\n );\r\n\r\n return values;\r\n}\r\n\r\n/**\r\n * Return a transformed local position from a mesh and vertex index\r\n * @param mesh mesh used to get vertex array from\r\n * @param index vertex index\r\n * @param res resulting local position\r\n * @returns false if it was not possible to compute the position for that vertex\r\n */\r\nexport function GetTransformedPosition(mesh: AbstractMesh, index: number, res: Vector3): boolean {\r\n const positions = GetVertexElementData(mesh, index, VertexBuffer.PositionKind);\r\n if (!positions) {\r\n return false;\r\n }\r\n\r\n if (positions.some((value) => isNaN(value ?? Number.NaN))) {\r\n return false;\r\n }\r\n\r\n if (mesh.morphTargetManager) {\r\n const base = index * 3;\r\n for (let i = 0; i < positions.length; i++) {\r\n let value = positions[i];\r\n for (let targetCount = 0; targetCount < mesh.morphTargetManager.numTargets; targetCount++) {\r\n const target = mesh.morphTargetManager.getTarget(targetCount);\r\n const influence = target.influence;\r\n if (influence !== 0) {\r\n const targetData = target.getPositions();\r\n if (targetData) {\r\n value += (targetData[base + i] - positions[i]) * influence;\r\n }\r\n }\r\n }\r\n positions[i] = value;\r\n }\r\n }\r\n\r\n res.fromArray(positions);\r\n\r\n if (mesh.skeleton) {\r\n const matricesIndicesData = GetVertexElementData(mesh, index, VertexBuffer.MatricesIndicesKind);\r\n const matricesWeightsData = GetVertexElementData(mesh, index, VertexBuffer.MatricesWeightsKind);\r\n if (matricesIndicesData && matricesWeightsData) {\r\n const needExtras = mesh.numBoneInfluencers > 4;\r\n const matricesIndicesExtraData = needExtras ? GetVertexElementData(mesh, index, VertexBuffer.MatricesIndicesExtraKind) : null;\r\n const matricesWeightsExtraData = needExtras ? GetVertexElementData(mesh, index, VertexBuffer.MatricesWeightsExtraKind) : null;\r\n const skeletonMatrices = mesh.skeleton.getTransformMatrices(mesh);\r\n\r\n const finalMatrix = TmpVectors.Matrix[0];\r\n const tempMatrix = TmpVectors.Matrix[1];\r\n\r\n finalMatrix.reset();\r\n\r\n for (let i = 0; i < matricesWeightsData.length; i++) {\r\n const weight = matricesWeightsData[i];\r\n if (weight > 0) {\r\n Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesData[i] * 16), weight, tempMatrix);\r\n finalMatrix.addToSelf(tempMatrix);\r\n }\r\n }\r\n if (matricesIndicesExtraData && matricesWeightsExtraData) {\r\n for (let i = 0; i < matricesWeightsExtraData.length; i++) {\r\n const weight = matricesWeightsExtraData[i];\r\n if (weight > 0) {\r\n Matrix.FromFloat32ArrayToRefScaled(skeletonMatrices, Math.floor(matricesIndicesExtraData[i] * 16), weight, tempMatrix);\r\n finalMatrix.addToSelf(tempMatrix);\r\n }\r\n }\r\n }\r\n\r\n Vector3.TransformCoordinatesFromFloatsToRef(positions[0], positions[1], positions[2], finalMatrix, res);\r\n }\r\n }\r\n\r\n return true;\r\n}\r\n\r\n/**\r\n * Compute a world space hotspot position\r\n * TmpVectors.Vector3[0..4] are modified by this function. Do not use them as result output.\r\n * @param mesh mesh used to get hotspot from\r\n * @param hotSpotQuery point indices and barycentric\r\n * @param resPosition output world position\r\n * @param resNormal optional output world normal\r\n * @returns false if it was not possible to compute the hotspot position\r\n */\r\nexport function GetHotSpotToRef(mesh: AbstractMesh, hotSpotQuery: HotSpotQuery, resPosition: Vector3, resNormal?: Vector3): boolean {\r\n resPosition.set(0, 0, 0);\r\n for (let i = 0; i < 3; i++) {\r\n const index = hotSpotQuery.pointIndex[i];\r\n if (!GetTransformedPosition(mesh, index, TmpVectors.Vector3[i])) {\r\n return false;\r\n }\r\n TmpVectors.Vector3[i].scaleAndAddToRef(hotSpotQuery.barycentric[i], resPosition);\r\n }\r\n\r\n // Convert the result to world space\r\n Vector3.TransformCoordinatesToRef(resPosition, mesh.getWorldMatrix(), resPosition);\r\n\r\n // compute normal in world space\r\n if (resNormal) {\r\n const pointA = TmpVectors.Vector3[0];\r\n const pointB = TmpVectors.Vector3[1];\r\n const pointC = TmpVectors.Vector3[2];\r\n const segmentA = TmpVectors.Vector3[3];\r\n const segmentB = TmpVectors.Vector3[4];\r\n segmentA.copyFrom(pointB);\r\n segmentA.subtractInPlace(pointA);\r\n segmentB.copyFrom(pointC);\r\n segmentB.subtractInPlace(pointA);\r\n segmentA.normalize();\r\n segmentB.normalize();\r\n Vector3.CrossToRef(segmentA, segmentB, resNormal);\r\n\r\n // flip normal when face culling is changed\r\n const flipNormal =\r\n mesh.material &&\r\n mesh.material.sideOrientation ===\r\n (mesh.getScene().useRightHandedSystem ? Constants.MATERIAL_ClockWiseSideOrientation : Constants.MATERIAL_CounterClockWiseSideOrientation);\r\n\r\n if (flipNormal) {\r\n resNormal.scaleInPlace(-1);\r\n }\r\n\r\n // Convert the result to world space\r\n Vector3.TransformNormalToRef(resNormal, mesh.getWorldMatrix(), resNormal);\r\n resNormal.normalize();\r\n }\r\n\r\n return true;\r\n}\r\n"]}
|