Open bordeck opened 10 years ago
Same here, I tried doing the conversion from the bunny example, but I get all the same errors as @bordeck:
Vertex 553: (-4591.5,-4447.42,-113.096) cannon.js:2365
Face normal 69 (0.25750913918348467,0.08884519204742058,-0.9621827139826602) looks like it points into the shape? The vertices follow. Make sure they are ordered CCW around the normal, using the right hand rule.
I'm trying to create a ConvexPolyhedron to represent this model: https://github.com/satellite-game/Satellite-Mobile/blob/master/client/game/models/phobos_hifi.json
Any update on this? It's been 19 months and this still seems to be an issue. I'm able to copy over Threejs geometry to form a convex hull but the hull does not act properly with collisions and I get the same errors as above. I added a wireframe rendering of the hull and I am confident that the vertices and faces in the hull are correct (also working with a simple cube just for debugging). Is this a bug or is more info (such as normals etc) needed for the constructor? There's minimal documentation on how to manage this.
Don't think there's any updates to the convex class that would help. However, I could give a few pointers.
Greetings everyone.
Convex polyhedron never behaved correctly for me with more complex shapes. To fix this, I created a Python script with blender that parses the boxes in a collection, which you should name "Colliders," then it will print out json format text in the console, and using that json file I parse it and generate the proper box colliders in my game.
Here is the blender python script:
import bpy
import math
collection = bpy.data.collections.get("Colliders")
# Get all objects in the scene
all_objects = collection.objects
# Count meshes for formatting
meshCount = 0
for obj in all_objects:
if obj.type == 'MESH':
meshCount += 1
# Print mesh information using ID counter
objectID = 0
print("{")
for obj in all_objects:
if obj.type == 'MESH':
print(" \"box_" + str(objectID) + "\":{")
# Position
position = obj.location
print(" \"position\":{")
print(" \"x\":" + str(position.x) + ",")
print(" \"y\":" + str(position.y) + ",")
print(" \"z\":" + str(position.z))
print(" },")
# Scale
scale = obj.scale
print(" \"scale\":{")
print(" \"x\":" + str(scale.x) + ",")
print(" \"y\":" + str(scale.y) + ",")
print(" \"z\":" + str(scale.z))
print(" },")
# Rotation (Euler)
rotation = obj.rotation_euler
print(" \"rotation\":{")
print(" \"x\":" + str(math.degrees(rotation.x)) + ",")
print(" \"y\":" + str(math.degrees(rotation.y)) + ",")
print(" \"z\":" + str(math.degrees(rotation.z)))
print(" }")
if(objectID != meshCount - 1):
print(" },\n")
else:
print(" }")
objectID += 1
print("}")
That will generate the json text. Copy that from your console, paste it in a .json file, and parse it like so in a js file with cannon:
/*
* Creating the level collision geometry
*/
async function GenerateLevelColliders(){
// RigidBody
levelRigidbody = new CANNON.Body({
type: CANNON.Body.STATIC
});
// Parse the JSON file
await fetch("levelColliders/level_" + currentLevel + ".json")
.then(response => response.json())
.then(data => {
let boxID = 0;
for (let boxKey in data) {
if(data.hasOwnProperty(boxKey)){
const box = data[boxKey];
const position = box.position;
const scale = box.scale;
const rotation = box.rotation;
let boxShape = new CANNON.Box(new CANNON.Vec3(scale.x, scale.y, scale.z));
// Set the last box as the "checkpoint"
if(boxID == Object.keys(data).length - 1){
// Create a specific body for final shape
levelEndRigidbody = new CANNON.Body({
type: CANNON.Body.STATIC
});
// Add its box
levelEndRigidbody.addShape(
boxShape,
new CANNON.Vec3(position.x , position.z, -position.y), // ~ Y is up in blender
EulerToQuaternion(rotation.x + 90, rotation.z, -rotation.y)
);
} else {
// Add each other box given position, scale and rotation
levelRigidbody.addShape(
boxShape,
new CANNON.Vec3(position.x , position.z, -position.y), // ~ Y is up in blender
EulerToQuaternion(rotation.x + 90, rotation.z, -rotation.y)
);
}
boxID += 1;
}
}
})
.catch(error => {
console.error('Error parsing JSON file:', error);
});
// Add the bodies
PhysicsWorld.addBody(levelRigidbody);
PhysicsWorld.addBody(levelEndRigidbody);
console.log("Finished loading: levelColliders/level_" + currentLevel + ".json ☑");
}
Keep in mind you must:
Hope this is helpful for game devs building larger levels with a bunch of colliders. The only downside to this is your colliders will use only boxes as primitives, but I'm sure this pipeline can be applied to spheres, and even tris.
Hello!
Thank you for this awesome library!!!
I'm working on a mesh fracturation on threejs meshs and i want to include your library into my project and especially to the fractured meshs. My current problem is that i don't find the solution to convert a convex mesh from threejs to the cannonjs. I'm a little bit lost with ConvexPolyhedron parameters. I have already convert the vertices and i can see the fractured mesh moving on the ground but i need to use a collisionFilterMask (to prevent collision) on them because the cannon bodies haven't faces. As i'm not skilled in 3d, I have tried to implement the solution you have wrote for the bunny but i have lots of warnings like "looks like it points into the shape? The vertices follow. Make sure they are ordered CCW around the normal, using the right hand rule." and i don't know how to fix this.
I hope it's the right place to ask you a solution and thanks in advance for your answer.