Closed rrelmy closed 3 years ago
@rrelmy you have to make the spoon body thicker.
Physics engines work on something called Discrete collision detection. Here's Box2D creator explaining it if you want to learn more:https://youtu.be/7_nKOET6zwI?t=211
@marcofugaro Thank you very much for the hint.
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.
We tried to get collisions between different convex polyhedrons based on simplified models loaded as GLB.
The collisions are very unreliable but happen sometimes, most of the time objects just fall through each other. Against planes and boxes the models behave as expected but not on each other.
I am not sure if the problem is with the models or the implementation. Is there some documentation about requirements to make such things possible?
Demo (red objects are fixed): https://eww7v.csb.app/