I want to add the canon body to all the Mesh Child elements in my scene loaded from the GLTF loader.
For now, I have one gltf mesh. which I loaded with this code:
async function load_model() {
const gltfLoader = new GLTFLoader()
await gltfLoader.setPath('./models/').load('scene.gltf', function (gltf) {
gltf.scene.traverse(function (child) {
if (child instanceof THREE.Mesh) {
console.log('hi')
const _child = child as THREE.Mesh
// computing bounding box for it's geometry
// we only have to compute it's bounding box because this is static mesh
_child.geometry.computeBoundingBox() //AABB
_child.castShadow = true
_child.receiveShadow = true
_child.scale.set(100, 100, 100)
sceneObjects.push(child)
}
if (child instanceof THREE.Light) {
const _light = child as THREE.Light
_light.castShadow = true
_light.shadow.bias = 0.0008 // to reduce artifact in shadow
_light.shadow.mapSize.width = 1024
_light.shadow.mapSize.height = 1024
}
})
scene.add(gltf.scene)
})
{
;(document.getElementById('loader') as HTMLDivElement).style.display = 'none'
;(mainscreen as HTMLElement).style.display = 'block'
}
}
load_model()
When the model is loaded I executed this code:
function getCenterPoint(mesh) {
var geometry = mesh.geometry
geometry.computeBoundingBox()
var center = new THREE.Vector3()
geometry.boundingBox.getCenter(center)
mesh.localToWorld(center)
return center
}
sceneObjects.forEach((element, index) => {
let itemsBody: CANNON.Body = new CANNON.Body({
mass: 0,
shape: new CANNON.Sphere(1),
})
let target = new THREE.Vector3()
target = getCenterPoint(element)
itemsBody.position.copy(new CANNON.Vec3(target.x, target.y, target.z))
world.addBody(itemsBody)
RoomsItemBody.push(itemsBody)
})
})
I am using DebugRenderer by @seanwasere so I can see the wireframe of the wireframe of the physics body of each mesh, (I am basically following his whole tutorial and i have checked all canon tutorial but in his tutorial, he is adding body on each mesh not on child of mesh ) I learnt lot from his example but i am stuck on this after trying everything i am not able to solve this.
Initially i tried
child.position inside the traversal but it gives vector3(0, 0, 0)
Any child object3ds within a hierarchy of object3ds use local position relative to the parent that they are a child of.
Maybe you want to consider the child meshes world position, when setting or updating the position of the cannon body.
In this exmaple, I add a cannon body to the left foot of this imported gltf. The left foot is several layers down the hierarchy.
See line 323 in my supplied code, for where I get the left foots world position and quaternion, before using it to update the cannon bodies position and quaternion.
Thank you so much. I checked this kick boxing demo as well but when i iterated my child meshes and called getworldPosition, they all returned vec3(0,0,0)
Instead of trying to auto create cannon bodies from the geometry, you should manually place bodies in the cannon world.
Your model is not set up to automatically generate physics bodies reliably.
If I open your model in blender, and look at just one of the objects, this is what I see.
If I view any of the objects, they look much the same.
So, the centre of that object, and all the other objects in your model, are roughly centred in the middle of the larger model. Just like the cannon debugger is showing you when you try to place a sphere body at the position you calculated from the objects geometry vertices.
I think, that you think, that each chair and table is a separate model. but it isn’t.
If you really wanted to get the positions from your model as it loads, then the simplest thing you could do in Blender, is create some empties at the locations you want.
And name them something useful,
And then as you traverse your model, check the objects names, and if they match what you want, get the position of the empty, scale it if you need since it looks like your model is using 1unit = !1m. And then add your cannon body at this location.
If this is too simple, and you prefer a more engineered gloss over your code, then you could add custom properties to each blender object, make sure you tick include → custom properties when you export from Blender, and then you can read that data via the child’s userData as you traverse.
You have many options.
Here is an example of extracting userData from the loaded model. I use it for the annotations.
Example : Glasses
I think the mesh is so messed up in terms of modeling because it looks like it is not something made in modeling software but is something that is made by scanning.
In this kind of model, what do you think is the best way to achieve what I want to achieve?
I can see nowadays lot of models are from the scanned result of the iPhone. How can I achieve this in this kind of 3D model?