Skip to content

Commit

Permalink
Merge pull request #1602 from xeokit/XEOK-83-fix-parseNodeMesh-null-m…
Browse files Browse the repository at this point in the history
…atrix-handling

XEOK-83 Fix null matrix handling in parseNodeMesh
  • Loading branch information
xeolabs authored Jul 31, 2024
2 parents 57cd7f1 + c809c4e commit c4abfe7
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 26 deletions.
21 changes: 15 additions & 6 deletions dist/xeokit-sdk.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -20504,6 +20504,8 @@ const Renderer$1 = function (scene, options) {
// result 1) regular hi-precision world position

let worldPos = null;
let worldNormal = null;
let pickable = null;

const middleX = snapRadiusInPixels;
const middleY = snapRadiusInPixels;
Expand All @@ -20521,7 +20523,7 @@ const Renderer$1 = function (scene, options) {
pickResultMiddleXY[1] * scale[1] + origin[1],
pickResultMiddleXY[2] * scale[2] + origin[2],
];
math.normalizeVec3([
worldNormal = math.normalizeVec3([
pickNormalResultMiddleXY[0] / math.MAX_INT,
pickNormalResultMiddleXY[1] / math.MAX_INT,
pickNormalResultMiddleXY[2] / math.MAX_INT,
Expand All @@ -20533,7 +20535,7 @@ const Renderer$1 = function (scene, options) {
+ (pickPickableResultMiddleXY[2] << 16)
+ (pickPickableResultMiddleXY[3] << 24);

pickIDs.items[pickID];
pickable = pickIDs.items[pickID];
}

// result 2) hi-precision snapped (to vertex/edge) world position
Expand Down Expand Up @@ -20630,13 +20632,16 @@ const Renderer$1 = function (scene, options) {
}

const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
if (!snappedEntity && pickable) {
pickable = pickable.delegatePickedEntity ? pickable.delegatePickedEntity() : pickable;
}

pickResult.reset();
pickResult.snappedToEdge = (snapType === "edge");
pickResult.snappedToVertex = (snapType === "vertex");
pickResult.worldPos = snappedWorldPos;
pickResult.worldNormal = snappedWorldNormal;
pickResult.entity = snappedEntity;
pickResult.worldPos = snappedWorldPos || worldPos;
pickResult.worldNormal = snappedWorldNormal || worldNormal;
pickResult.entity = snappedEntity || pickable;
pickResult.canvasPos = canvasPos || scene.camera.projectWorldPos(worldPos || snappedWorldPos);
pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;

Expand Down Expand Up @@ -118346,7 +118351,11 @@ function parseNodeMesh(node, ctx, matrix, meshIds) {
if (primitive.indices) {
meshCfg.indices = primitive.indices.value;
}
math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
if (matrix) {
math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
} else { // eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);
meshCfg.positions.set(meshCfg.localPositions);
}
const origin = math.vec3();
const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
if (rtcNeeded) {
Expand Down
21 changes: 15 additions & 6 deletions dist/xeokit-sdk.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -20500,6 +20500,8 @@ const Renderer$1 = function (scene, options) {
// result 1) regular hi-precision world position

let worldPos = null;
let worldNormal = null;
let pickable = null;

const middleX = snapRadiusInPixels;
const middleY = snapRadiusInPixels;
Expand All @@ -20517,7 +20519,7 @@ const Renderer$1 = function (scene, options) {
pickResultMiddleXY[1] * scale[1] + origin[1],
pickResultMiddleXY[2] * scale[2] + origin[2],
];
math.normalizeVec3([
worldNormal = math.normalizeVec3([
pickNormalResultMiddleXY[0] / math.MAX_INT,
pickNormalResultMiddleXY[1] / math.MAX_INT,
pickNormalResultMiddleXY[2] / math.MAX_INT,
Expand All @@ -20529,7 +20531,7 @@ const Renderer$1 = function (scene, options) {
+ (pickPickableResultMiddleXY[2] << 16)
+ (pickPickableResultMiddleXY[3] << 24);

pickIDs.items[pickID];
pickable = pickIDs.items[pickID];
}

// result 2) hi-precision snapped (to vertex/edge) world position
Expand Down Expand Up @@ -20626,13 +20628,16 @@ const Renderer$1 = function (scene, options) {
}

const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
if (!snappedEntity && pickable) {
pickable = pickable.delegatePickedEntity ? pickable.delegatePickedEntity() : pickable;
}

pickResult.reset();
pickResult.snappedToEdge = (snapType === "edge");
pickResult.snappedToVertex = (snapType === "vertex");
pickResult.worldPos = snappedWorldPos;
pickResult.worldNormal = snappedWorldNormal;
pickResult.entity = snappedEntity;
pickResult.worldPos = snappedWorldPos || worldPos;
pickResult.worldNormal = snappedWorldNormal || worldNormal;
pickResult.entity = snappedEntity || pickable;
pickResult.canvasPos = canvasPos || scene.camera.projectWorldPos(worldPos || snappedWorldPos);
pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;

Expand Down Expand Up @@ -118342,7 +118347,11 @@ function parseNodeMesh(node, ctx, matrix, meshIds) {
if (primitive.indices) {
meshCfg.indices = primitive.indices.value;
}
math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
if (matrix) {
math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
} else { // eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);
meshCfg.positions.set(meshCfg.localPositions);
}
const origin = math.vec3();
const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
if (rtcNeeded) {
Expand Down
7 changes: 4 additions & 3 deletions dist/xeokit-sdk.es5.js
Original file line number Diff line number Diff line change
Expand Up @@ -4885,10 +4885,10 @@ drawable.setPickMatrices(frameCtx.pickViewMatrix,pickProjMatrix);}}}}// a) init
gl.drawBuffers([gl.COLOR_ATTACHMENT0,gl.COLOR_ATTACHMENT1,gl.COLOR_ATTACHMENT2]);var layerParamsSurface=drawSnapInit(frameCtx);// b) snap-pick
var layerParamsSnap=[];frameCtx.snapPickLayerParams=layerParamsSnap;gl.depthMask(false);gl.drawBuffers([gl.COLOR_ATTACHMENT0]);if(snapToVertex&&snapToEdge){frameCtx.snapMode="edge";drawSnap(frameCtx);frameCtx.snapMode="vertex";frameCtx.snapPickLayerNumber++;drawSnap(frameCtx);}else{frameCtx.snapMode=snapToVertex?"vertex":"edge";drawSnap(frameCtx);}gl.depthMask(true);// Read and decode the snapped coordinates
var snapPickResultArray=vertexPickBuffer.readArray(gl.RGBA_INTEGER,gl.INT,Int32Array,4);var snapPickNormalResultArray=vertexPickBuffer.readArray(gl.RGBA_INTEGER,gl.INT,Int32Array,4,1);var snapPickIdResultArray=vertexPickBuffer.readArray(gl.RGBA_INTEGER,gl.UNSIGNED_INT,Uint32Array,4,2);vertexPickBuffer.unbind();// result 1) regular hi-precision world position
var worldPos=null;var middleX=snapRadiusInPixels;var middleY=snapRadiusInPixels;var middleIndex=middleX*4+middleY*vertexPickBuffer.size[0]*4;var pickResultMiddleXY=snapPickResultArray.slice(middleIndex,middleIndex+4);var pickNormalResultMiddleXY=snapPickNormalResultArray.slice(middleIndex,middleIndex+4);var pickPickableResultMiddleXY=snapPickIdResultArray.slice(middleIndex,middleIndex+4);if(pickResultMiddleXY[3]!==0){var pickedLayerParmasSurface=layerParamsSurface[Math.abs(pickResultMiddleXY[3])%layerParamsSurface.length];var _origin=pickedLayerParmasSurface.origin;var _scale=pickedLayerParmasSurface.coordinateScale;worldPos=[pickResultMiddleXY[0]*_scale[0]+_origin[0],pickResultMiddleXY[1]*_scale[1]+_origin[1],pickResultMiddleXY[2]*_scale[2]+_origin[2]];math.normalizeVec3([pickNormalResultMiddleXY[0]/math.MAX_INT,pickNormalResultMiddleXY[1]/math.MAX_INT,pickNormalResultMiddleXY[2]/math.MAX_INT]);var pickID=pickPickableResultMiddleXY[0]+(pickPickableResultMiddleXY[1]<<8)+(pickPickableResultMiddleXY[2]<<16)+(pickPickableResultMiddleXY[3]<<24);pickIDs.items[pickID];}// result 2) hi-precision snapped (to vertex/edge) world position
var worldPos=null;var worldNormal=null;var pickable=null;var middleX=snapRadiusInPixels;var middleY=snapRadiusInPixels;var middleIndex=middleX*4+middleY*vertexPickBuffer.size[0]*4;var pickResultMiddleXY=snapPickResultArray.slice(middleIndex,middleIndex+4);var pickNormalResultMiddleXY=snapPickNormalResultArray.slice(middleIndex,middleIndex+4);var pickPickableResultMiddleXY=snapPickIdResultArray.slice(middleIndex,middleIndex+4);if(pickResultMiddleXY[3]!==0){var pickedLayerParmasSurface=layerParamsSurface[Math.abs(pickResultMiddleXY[3])%layerParamsSurface.length];var _origin=pickedLayerParmasSurface.origin;var _scale=pickedLayerParmasSurface.coordinateScale;worldPos=[pickResultMiddleXY[0]*_scale[0]+_origin[0],pickResultMiddleXY[1]*_scale[1]+_origin[1],pickResultMiddleXY[2]*_scale[2]+_origin[2]];worldNormal=math.normalizeVec3([pickNormalResultMiddleXY[0]/math.MAX_INT,pickNormalResultMiddleXY[1]/math.MAX_INT,pickNormalResultMiddleXY[2]/math.MAX_INT]);var pickID=pickPickableResultMiddleXY[0]+(pickPickableResultMiddleXY[1]<<8)+(pickPickableResultMiddleXY[2]<<16)+(pickPickableResultMiddleXY[3]<<24);pickable=pickIDs.items[pickID];}// result 2) hi-precision snapped (to vertex/edge) world position
var snapPickResult=[];for(var _i74=0;_i74<snapPickResultArray.length;_i74+=4){if(snapPickResultArray[_i74+3]>0){var pixelNumber=Math.floor(_i74/4);var w=vertexPickBuffer.size[0];var x=pixelNumber%w-Math.floor(w/2);var y=Math.floor(pixelNumber/w)-Math.floor(w/2);var dist=Math.sqrt(Math.pow(x,2)+Math.pow(y,2));snapPickResult.push({x:x,y:y,dist:dist,isVertex:snapToVertex&&snapToEdge?snapPickResultArray[_i74+3]>layerParamsSnap.length/2:snapToVertex,result:[snapPickResultArray[_i74+0],snapPickResultArray[_i74+1],snapPickResultArray[_i74+2],snapPickResultArray[_i74+3]],normal:[snapPickNormalResultArray[_i74+0],snapPickNormalResultArray[_i74+1],snapPickNormalResultArray[_i74+2],snapPickNormalResultArray[_i74+3]],id:[snapPickIdResultArray[_i74+0],snapPickIdResultArray[_i74+1],snapPickIdResultArray[_i74+2],snapPickIdResultArray[_i74+3]]});}}var snappedWorldPos=null;var snappedWorldNormal=null;var snappedPickable=null;var snapType=null;if(snapPickResult.length>0){// vertex snap first, then edge snap
snapPickResult.sort(function(a,b){if(a.isVertex!==b.isVertex){return a.isVertex?-1:1;}else{return a.dist-b.dist;}});snapType=snapPickResult[0].isVertex?"vertex":"edge";var snapPick=snapPickResult[0].result;var snapPickNormal=snapPickResult[0].normal;var snapPickId=snapPickResult[0].id;var pickedLayerParmas=layerParamsSnap[snapPick[3]];var _origin2=pickedLayerParmas.origin;var _scale2=pickedLayerParmas.coordinateScale;snappedWorldNormal=math.normalizeVec3([snapPickNormal[0]/math.MAX_INT,snapPickNormal[1]/math.MAX_INT,snapPickNormal[2]/math.MAX_INT]);snappedWorldPos=[snapPick[0]*_scale2[0]+_origin2[0],snapPick[1]*_scale2[1]+_origin2[1],snapPick[2]*_scale2[2]+_origin2[2]];snappedPickable=pickIDs.items[snapPickId[0]+(snapPickId[1]<<8)+(snapPickId[2]<<16)+(snapPickId[3]<<24)];}if(null===worldPos&&null==snappedWorldPos){// If neither regular pick or snap pick, return null
return null;}var snappedCanvasPos=null;if(null!==snappedWorldPos){snappedCanvasPos=scene.camera.projectWorldPos(snappedWorldPos);}var snappedEntity=snappedPickable&&snappedPickable.delegatePickedEntity?snappedPickable.delegatePickedEntity():snappedPickable;pickResult.reset();pickResult.snappedToEdge=snapType==="edge";pickResult.snappedToVertex=snapType==="vertex";pickResult.worldPos=snappedWorldPos;pickResult.worldNormal=snappedWorldNormal;pickResult.entity=snappedEntity;pickResult.canvasPos=canvasPos||scene.camera.projectWorldPos(worldPos||snappedWorldPos);pickResult.snappedCanvasPos=snappedCanvasPos||canvasPos;return pickResult;};}();function unpackDepth(depthZ){var vec=[depthZ[0]/256.0,depthZ[1]/256.0,depthZ[2]/256.0,depthZ[3]/256.0];var bitShift=[1.0/(256.0*256.0*256.0),1.0/(256.0*256.0),1.0/256.0,1.0];return math.dotVec4(vec,bitShift);}function gpuPickWorldNormal(pickBuffer,pickable,canvasPos,pickViewMatrix,pickProjMatrix,pickResult){var resolutionScale=scene.canvas.resolutionScale;frameCtx.reset();frameCtx.backfaces=true;frameCtx.frontface=true;// "ccw"
return null;}var snappedCanvasPos=null;if(null!==snappedWorldPos){snappedCanvasPos=scene.camera.projectWorldPos(snappedWorldPos);}var snappedEntity=snappedPickable&&snappedPickable.delegatePickedEntity?snappedPickable.delegatePickedEntity():snappedPickable;if(!snappedEntity&&pickable){pickable=pickable.delegatePickedEntity?pickable.delegatePickedEntity():pickable;}pickResult.reset();pickResult.snappedToEdge=snapType==="edge";pickResult.snappedToVertex=snapType==="vertex";pickResult.worldPos=snappedWorldPos||worldPos;pickResult.worldNormal=snappedWorldNormal||worldNormal;pickResult.entity=snappedEntity||pickable;pickResult.canvasPos=canvasPos||scene.camera.projectWorldPos(worldPos||snappedWorldPos);pickResult.snappedCanvasPos=snappedCanvasPos||canvasPos;return pickResult;};}();function unpackDepth(depthZ){var vec=[depthZ[0]/256.0,depthZ[1]/256.0,depthZ[2]/256.0,depthZ[3]/256.0];var bitShift=[1.0/(256.0*256.0*256.0),1.0/(256.0*256.0),1.0/256.0,1.0];return math.dotVec4(vec,bitShift);}function gpuPickWorldNormal(pickBuffer,pickable,canvasPos,pickViewMatrix,pickProjMatrix,pickResult){var resolutionScale=scene.canvas.resolutionScale;frameCtx.reset();frameCtx.backfaces=true;frameCtx.frontface=true;// "ccw"
frameCtx.pickOrigin=pickResult.origin;frameCtx.pickViewMatrix=pickViewMatrix;frameCtx.pickProjMatrix=pickProjMatrix;frameCtx.pickClipPos=[getClipPosX(canvasPos[0]*resolutionScale,gl.drawingBufferWidth),getClipPosY(canvasPos[1]*resolutionScale,gl.drawingBufferHeight)];var pickNormalBuffer=renderBufferManager.getRenderBuffer("pick-normal",{size:[3,3]});pickNormalBuffer.bind(gl.RGBA32I);gl.viewport(0,0,pickNormalBuffer.size[0],pickNormalBuffer.size[1]);gl.enable(gl.DEPTH_TEST);gl.disable(gl.CULL_FACE);gl.disable(gl.BLEND);gl.clear(gl.DEPTH_BUFFER_BIT);gl.clearBufferiv(gl.COLOR,0,new Int32Array([0,0,0,0]));pickable.drawPickNormals(frameCtx);// Draw color-encoded fragment World-space normals
var pix=pickNormalBuffer.read(1,1,gl.RGBA_INTEGER,gl.INT,Int32Array,4);pickNormalBuffer.unbind();var worldNormal=[pix[0]/math.MAX_INT,pix[1]/math.MAX_INT,pix[2]/math.MAX_INT];math.normalizeVec3(worldNormal);pickResult.worldNormal=worldNormal;}/**
* Adds a {@link Marker} for occlusion testing.
Expand Down Expand Up @@ -25068,7 +25068,8 @@ meshCfg.primitive="lines";break;case 3:// LINE_STRIP
meshCfg.primitive="lines";break;case 4:// TRIANGLES
meshCfg.primitive=backfaces?"triangles":"solid";break;case 5:// TRIANGLE_STRIP
meshCfg.primitive=backfaces?"triangles":"solid";break;case 6:// TRIANGLE_FAN
meshCfg.primitive=backfaces?"triangles":"solid";break;default:meshCfg.primitive=backfaces?"triangles":"solid";}var POSITION=_primitive4.attributes.POSITION;if(!POSITION){continue;}meshCfg.localPositions=POSITION.value;meshCfg.positions=new Float64Array(meshCfg.localPositions.length);if(_primitive4.attributes.NORMAL){meshCfg.normals=_primitive4.attributes.NORMAL.value;}if(_primitive4.attributes.TEXCOORD_0){meshCfg.uv=_primitive4.attributes.TEXCOORD_0.value;}if(_primitive4.indices){meshCfg.indices=_primitive4.indices.value;}math.transformPositions3(matrix,meshCfg.localPositions,meshCfg.positions);var origin=math.vec3();var rtcNeeded=worldToRTCPositions(meshCfg.positions,meshCfg.positions,origin);// Small cellsize guarantees better accuracy
meshCfg.primitive=backfaces?"triangles":"solid";break;default:meshCfg.primitive=backfaces?"triangles":"solid";}var POSITION=_primitive4.attributes.POSITION;if(!POSITION){continue;}meshCfg.localPositions=POSITION.value;meshCfg.positions=new Float64Array(meshCfg.localPositions.length);if(_primitive4.attributes.NORMAL){meshCfg.normals=_primitive4.attributes.NORMAL.value;}if(_primitive4.attributes.TEXCOORD_0){meshCfg.uv=_primitive4.attributes.TEXCOORD_0.value;}if(_primitive4.indices){meshCfg.indices=_primitive4.indices.value;}if(matrix){math.transformPositions3(matrix,meshCfg.localPositions,meshCfg.positions);}else{// eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);
meshCfg.positions.set(meshCfg.localPositions);}var origin=math.vec3();var rtcNeeded=worldToRTCPositions(meshCfg.positions,meshCfg.positions,origin);// Small cellsize guarantees better accuracy
if(rtcNeeded){meshCfg.origin=origin;}ctx.sceneModel.createMesh(meshCfg);meshIds.push(meshCfg.id);}}}function error(ctx,msg){ctx.plugin.error(msg);}/**
* @desc Default initial properties for {@link Entity}s loaded from models accompanied by metadata.
*
Expand Down
8 changes: 4 additions & 4 deletions dist/xeokit-sdk.min.cjs.js

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions dist/xeokit-sdk.min.es.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/xeokit-sdk.min.es5.js

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,11 @@ function parseNodeMesh(node, ctx, matrix, meshIds) {
if (primitive.indices) {
meshCfg.indices = primitive.indices.value;
}
math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
if (matrix) {
math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
} else { // eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);
meshCfg.positions.set(meshCfg.localPositions);
}
const origin = math.vec3();
const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
if (rtcNeeded) {
Expand Down

0 comments on commit c4abfe7

Please sign in to comment.