Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading from OBJ to ConvexPolyhedron #498

Open
zlatnaspirala opened this issue Jan 17, 2025 · 0 comments
Open

Loading from OBJ to ConvexPolyhedron #498

zlatnaspirala opened this issue Jan 17, 2025 · 0 comments

Comments

@zlatnaspirala
Copy link

zlatnaspirala commented Jan 17, 2025

I will delete this issue after all , I just wanna try here maybe i will get some help.

I dont use threejs for render. I use my library and i have already nice working objLoader.

I need to load ConvexPolyhedron. If i use bunny.js data i get some results. Maybe some pixels under floor but it is ok for me.

If i use createTetra then works perfect.

	function createTetra() {
		var scale = 2;
		var verts = [
			new CANNON.Vec3(scale * 0, scale * 0, scale * 0),
			new CANNON.Vec3(scale * 1, scale * 0, scale * 0),
			new CANNON.Vec3(scale * 0, scale * 1, scale * 0),
			new CANNON.Vec3(scale * 0, scale * 0, scale * 1)];
		var offset = -0.35;
		for(var i = 0;i < verts.length;i++) {
			var v = verts[i];
			v.x += offset;
			v.y += offset;
			v.z += offset;
		}
		return new CANNON.ConvexPolyhedron(verts,
			[
				[0, 3, 2], // -x
				[0, 1, 3], // -y
				[0, 2, 1], // -z
				[1, 2, 3], // +xyz
			]);
	}

Here is some interest part :
It is a classic from demos...

	function fromObjToConvexPolyhedron(obj) {
		var scale = 2;
		console.log('OBJ::: ----')
		var rawVerts = obj.mesh.vertices;
		var rawFaces = obj.mesh.indices;
		var rawOffset = [0, 0, 0];
		var verts = [], faces = [], offset;
		for(var j = 0;j < rawVerts.length;j += 3) {
			verts.push(new CANNON.Vec3(rawVerts[j] * scale,
				rawVerts[j + 1] * scale,
				rawVerts[j + 2] * scale));
		}
		// Get faces
		for(var j = 0;j < rawFaces.length;j += 3) {
			faces.push([rawFaces[j], rawFaces[j + 1], rawFaces[j + 2]]);
		}
		offset = new CANNON.Vec3(rawOffset[0], rawOffset[1], rawOffset[2]);
		 return new CANNON.ConvexPolyhedron(verts, faces);
	}

My ObjLoader:

export class constructMesh {
	constructor(objectData, inputArg) {
		this.name = '';
		this.inputArg = inputArg;
		this.objectData = objectData;
		this.create(objectData, inputArg);
		this.setScale = (s) => {
			this.inputArg.scale = s;
			initMeshBuffers(world.GL.gl, this.create(this.objectData, this.inputArg, undefined, this));
		};
		// Never used
		this.updateBuffers = () => {
			this.inputArg.scale = 1;
			initMeshBuffers(world.GL.gl, this.create(this.objectData, this.inputArg, undefined, this));
		};
	}

	create = (objectData, inputArg, callback, root) => {
		if(typeof callback === 'undefined') callback = function() {};
		let initOrientation = [0, 1, 2];
		var verts = [],
			vertNormals = [],
			textures = [],
			unpacked = {};
		unpacked.verts = [];
		unpacked.norms = [];
		unpacked.textures = [];
		unpacked.hashindices = {};
		unpacked.indices = [];
		unpacked.index = 0;
		// array of lines separated by the newline
		var lines = objectData.split('\n');
		// test group catch data bpund or center
		var objGroups = [];
		// update swap orientation
		if(inputArg.swap[0] !== null) {
			swap(inputArg.swap[0], inputArg.swap[1], initOrientation);
		}

		var VERTEX_RE = /^v\s/;
		var NORMAL_RE = /^vn\s/;
		var TEXTURE_RE = /^vt\s/;
		var FACE_RE = /^f\s/;
		var WHITESPACE_RE = /\s+/;

		for(var i = 0;i < lines.length;i++) {
			var line = lines[i].trim();
			var elements = line.split(WHITESPACE_RE);
			elements.shift();
			if(VERTEX_RE.test(line)) {
				verts.push.apply(verts, elements);
				if(objGroups.length > 0) {
					objGroups[objGroups.length - 1].groupVert.push(elements)
				}
			} else if(NORMAL_RE.test(line)) {
				// if this is a vertex normal
				vertNormals.push.apply(vertNormals, elements);
			} else if(TEXTURE_RE.test(line)) {
				// if this is a texture
				textures.push.apply(textures, elements);
			} else if(FACE_RE.test(line)) {
				// if this is a face
				/*
					split this face into an array of vertex groups
					for example:
						f 16/92/11 14/101/22 1/69/1
					becomes:
						['16/92/11', '14/101/22', '1/69/1'];
					*/
				var quad = false;
				for(var j = 0, eleLen = elements.length;j < eleLen;j++) {
					// Triangulating quads
					// quad: 'f v0/t0/vn0 v1/t1/vn1 v2/t2/vn2 v3/t3/vn3/'
					// corresponding triangles:
					//      'f v0/t0/vn0 v1/t1/vn1 v2/t2/vn2'
					//      'f v2/t2/vn2 v3/t3/vn3 v0/t0/vn0'
					if(j === 3 && !quad) {
						// add v2/t2/vn2 in again before continuing to 3
						j = 2;
						quad = true;
					}
					if(elements[j] in unpacked.hashindices) {
						unpacked.indices.push(unpacked.hashindices[elements[j]]);
					} else {

						var vertex = elements[j].split('/');
						// vertex position + scale by axis
						if(typeof inputArg.scale == "number") {
							unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[0]] * inputArg.scale);
							unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[1]] * inputArg.scale);
							unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[2]] * inputArg.scale);
						} else {
							unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[0]] * inputArg.scale.x);
							unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[1]] * inputArg.scale.y);
							unpacked.verts.push(+verts[(vertex[0] - 1) * 3 + initOrientation[2]] * inputArg.scale.z);
						}
						// vertex textures
						if(textures.length) {
							unpacked.textures.push(+textures[(vertex[1] - 1) * 2 + 0]);
							unpacked.textures.push(+textures[(vertex[1] - 1) * 2 + 1]);
						}
						// vertex normals
						unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 0]);
						unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 1]);
						unpacked.norms.push(+vertNormals[(vertex[2] - 1) * 3 + 2]);
						// add the newly created vertex to the list of indices
						unpacked.hashindices[elements[j]] = unpacked.index;
						unpacked.indices.push(unpacked.index);
						// increment the counter
						unpacked.index += 1;
					}
					if(j === 3 && quad) {
						// add v0/t0/vn0 onto the second triangle
						unpacked.indices.push(unpacked.hashindices[elements[0]]);
					}
				}
			} else {
				if(line.indexOf('# ') != -1) {
					// console.log('obj loader comment:', line)
				} else if(line.indexOf('mtllib') != -1) {
					// console.log('obj loader MTL file:', line)
				} else if(line.indexOf('o ') != -1) {
					console.log('obj loader object name:', line.split(' ')[1])
					this.name = line.split(' ')[1]
				} else if(line.indexOf('g ') != -1) {
					// console.log('obj loader group :', line)
					var nameOFGroup = line.split(' ')[1]
					if(nameOFGroup.indexOf('COLLIDER') != -1) {
						// console.log('obj loader group [SPECIAL CASE COLLIDER]:', nameOFGroup)
						objGroups.push({
							groupName: nameOFGroup,
							groupVert: [],
							groupNorm: [],
							groupTexCord: [],
							groupIndices: []
						})
					} else if(nameOFGroup.indexOf('Destruct') != -1) {
						// console.log('obj loader group [SPECIAL CASE Destruct] [reset] :', nameOFGroup)
						objGroups.push({
							groupName: nameOFGroup,
							groupVert: [],
							groupNorm: [],
							groupTexCord: [],
							groupIndices: []
						})
					}
				}
			}
		}
		this.vertices = unpacked.verts;
		this.vertexNormals = unpacked.norms;
		this.textures = unpacked.textures;
		this.indices = unpacked.indices;

		verts = verts.map(function(item) {
			return parseFloat(item);
		});
		this.TEST_verts = verts;

		if(objGroups.length > 0) {
			this.groups = objGroups;
		} else {
			this.groups = null;
		}
		callback();
		return this;
	};
}

If i use cube obj file , default cube from blender.
Then works.

If i try to load somethig more complicated but still CONVEX they i get warn and error:

Image

Image

My last chance will be scaling because i spot long time ago fact:
If i use geo smaller then 1 or 2 then precision goes crazzy.

This object not pass :

Image

I miss something,
Any suggestion Thanks ...

For example i need to parse pyramid :

# Blender 4.1.1
# www.blender.org
mtllib meDestruct_cell_001.mtl
g Cube_Mesh
v -2.006763 -2.006763 2.006763
v 0.000000 2.006763 0.000000
v -2.006763 -2.006763 -2.006763
v 2.006763 -2.006763 2.006763
v 2.006763 -2.006763 -2.006763
vn -0.8944 0.4472 -0.0000
vn -0.0000 0.4472 -0.8944
vn 0.8944 0.4472 -0.0000
vn -0.0000 0.4472 0.8944
vn -0.0000 -1.0000 -0.0000
vt 0.375000 0.000000
vt 0.625000 0.250000
vt 0.375000 0.250000
vt 0.625000 0.500000
vt 0.375000 0.500000
vt 0.625000 0.750000
vt 0.375000 0.750000
vt 0.625000 1.000000
vt 0.375000 1.000000
vt 0.125000 0.750000
vt 0.125000 0.500000
s 0
f 1/1/1 2/2/1 3/3/1
f 3/3/2 2/4/2 5/5/2
f 5/5/3 2/6/3 4/7/3
f 4/7/4 2/8/4 1/9/4
f 5/5/5 1/10/5 3/11/5
f 5/5/5 4/7/5 1/10/5

What is the structure for faces argument in this case.
Pyramid angularVelocity not work - i got just position not rotation this case is most usual.
I try lot of combination no one works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant