-
-
Notifications
You must be signed in to change notification settings - Fork 36k
Closed as not planned
Closed as not planned
Copy link
Milestone
Description
Description
When using Box3.setFromBufferAttribute() on an InterleavedBufferAttribute, the resulting bounding box can be incorrect if the attribute has a non-zero offset. This is because fromBufferAttribute() does not appear to correctly take the offset into account for interleaved data.
In the setFromBufferAttribute function,the real count in loop should be equal to attribute.count - attribute.offset.Or attribute cout of interleavedBufferAttribute equal to attribute.data.count - attribute.offset
Reproduction steps
Steps to reproduce the behavior:
- Create a geometry using
InterleavedBufferAttribute
for positions. - Provide a non-zero
offset
- Call
box.setFromBufferAttribute(positionAttribute);
- The resulting box may be invalid or incorrect.
Code
const ReverseWindingOrder = function (idxArray: number[]) {
for (let i = 0; i < idxArray.length; i += 3) {
let tem = idxArray[i];
idxArray[i] = idxArray[i + 1];
idxArray[i + 1] = tem;
}
};
const posData = [
0, 0, 0, 0, 0, 0, 0, 0, 0,//0
1, 0, 0, 1, 0, 0, 1, 0, 0,//1
0, 0, 1, 0, 0, 1, 0, 0, 1,//2
1, 0, 1, 1, 0, 1, 1, 0, 1,//3
0, 1, 0, 0, 1, 0, 0, 1, 0,//4
1, 1, 0, 1, 1, 0, 1, 1, 0,//5
0, 1, 1, 0, 1, 1, 0, 1, 1,//6
1, 1, 1, 1, 1, 1, 1, 1, 1,//7
0, 0, 0, 0, 0, 0, 0, 0, 0,//0
2, 0, 0, 2, 0, 0, 2, 0, 0,//2
0, 0, 2, 0, 0, 2, 0, 0, 2,//2
2, 0, 2, 2, 0, 2, 2, 0, 2,//3
0, 2, 0, 0, 2, 0, 0, 2, 0,//4
2, 2, 0, 2, 2, 0, 2, 2, 0,//5
0, 2, 2, 0, 2, 2, 0, 2, 2,//6
2, 2, 2, 2, 2, 2, 2, 2, 2,//7
];
const idxData = [
1 * 3 + 0, 5 * 3 + 0, 7 * 3 + 0, 1 * 3 + 0, 7 * 3 + 0, 3 * 3 + 0,//+x
2 * 3 + 0, 6 * 3 + 0, 4 * 3 + 0, 2 * 3 + 0, 4 * 3 + 0, 0 * 3 + 0,//-x
4 * 3 + 1, 6 * 3 + 1, 5 * 3 + 1, 5 * 3 + 1, 6 * 3 + 1, 7 * 3 + 1,//+y
0 * 3 + 1, 1 * 3 + 1, 2 * 3 + 1, 2 * 3 + 1, 1 * 3 + 1, 3 * 3 + 1,//-y
2 * 3 + 2, 7 * 3 + 2, 6 * 3 + 2, 2 * 3 + 2, 3 * 3 + 2, 7 * 3 + 2,//+z
0 * 3 + 2, 4 * 3 + 2, 5 * 3 + 2, 0 * 3 + 2, 5 * 3 + 2, 1 * 3 + 2,//-z
1 * 3 + 0, 5 * 3 + 0, 7 * 3 + 0, 1 * 3 + 0, 7 * 3 + 0, 3 * 3 + 0,//+x
2 * 3 + 0, 6 * 3 + 0, 4 * 3 + 0, 2 * 3 + 0, 4 * 3 + 0, 0 * 3 + 0,//-x
4 * 3 + 1, 6 * 3 + 1, 5 * 3 + 1, 5 * 3 + 1, 6 * 3 + 1, 7 * 3 + 1,//+y
0 * 3 + 1, 1 * 3 + 1, 2 * 3 + 1, 2 * 3 + 1, 1 * 3 + 1, 3 * 3 + 1,//-y
2 * 3 + 2, 7 * 3 + 2, 6 * 3 + 2, 2 * 3 + 2, 3 * 3 + 2, 7 * 3 + 2,//+z
0 * 3 + 2, 4 * 3 + 2, 5 * 3 + 2, 0 * 3 + 2, 5 * 3 + 2, 1 * 3 + 2,//-z
];
ReverseWindingOrder(idxData);
const pos = new THREE.InterleavedBuffer(new Float32Array(posData),3);
const idx = new THREE.BufferAttribute(new Uint16Array(idxData), 1)
const geo = new THREE.BufferGeometry();
const attpos = new THREE.InterleavedBufferAttribute(pos,pos.stride,0);
geo.setAttribute('position',attpos);
geo.setIndex(idx);
geo.addGroup(0,36);
const geo0 = new THREE.BufferGeometry();
const attpos0 = new THREE.InterleavedBufferAttribute(pos,pos.stride,24 * pos.stride);
geo0.setAttribute('position',attpos0);
geo0.setIndex(idx);
geo0.addGroup(0,Infinity);
const material= new THREE.MeshStandardMaterial({
side:THREE.BackSide,
color: 0x00ff00,
metalness: 0.8,
roughness:0.5,
});
const cube = new THREE.Mesh(geo, [material]);
cube.position.set(5,0,0);
const cube0 = new THREE.Mesh(geo0, [material]);
cube0.position.set(10,0,0);
this.scene.add(cube);
this.scene.add(cube0);
Screenshots
No response
Version
r167
Device
No response
Browser
No response
OS
No response