Dear all,
I am fairly new to javascript and three.js. I have managed to load a custom 3D model using three.js. Now I want a ball to detect the “contour” of my 3D model. Except, I cannot manage to make it work and also I am trying to display the mesh that the ball should detect as collision and that does not work either. I will be grateful for your help. Please find my code below.
function createBaseMaze(){
let pos = {x: 0, y: 0, z: 0};
let scale = {x: 0.2, y: 0.2, z: 0.2};
let quat = {x: 0, y: 0, z: 0, w: 1};
let mass = 0;
//Ammojs Section
let concaveShape = new Ammo.btConvexHullShape();
let transform = new Ammo.btTransform();
let motionState = new Ammo.btDefaultMotionState( transform );
let localInertia = new Ammo.btVector3( 0, 0, 0 );
transform.setIdentity();
transform.setOrigin( new Ammo.btVector3( pos.x, pos.y, pos.z ) );
transform.setRotation( new Ammo.btQuaternion( quat.x, quat.y, quat.z, quat.w ) );
concaveShape.calculateLocalInertia( mass, localInertia );
let rbInfo, body;
console.log("MY Shape Before : ");
console.log(concaveShape.getNumVertices());
loader = new GLTFLoader().setPath('');
loader.load( 'Maze.gltf', async function ( gltf ) {
gltf.scene.scale.set(scale.x,scale.y,scale.z);
model = gltf.scene;
model.rotation.x=-Math.PI/2;
model.rotation.z=Math.PI/2;
model.position.set(pos.x,pos.y,pos.z);
model.traverse( function ( child) {
if(child instanceof THREE.Mesh) {
//Accéder à la géométrie du mesh
let geometry = child.geometry;
// Vérifier si la géométrie est un BufferGeometry
if (geometry instanceof THREE.BufferGeometry) {
// Obtenir les attributs de la géométrie
let positionAttribute = geometry.getAttribute('position');
// Récupérer les données des positions (sous forme de tableau TypedArray)
let positions = positionAttribute.array;
// Boucler à travers les données des positions pour former les triangles
for (let i = 0; i < positions.length; i += 9) {
// Créer un tableau pour stocker les coordonnées des sommets du triangle
//let triangle = [];
// Ajouter les coordonnées des sommets du triangle au tableau
let triangle = [
new Ammo.btVector3(positions[i], positions[i + 1], positions[i + 2]),
new Ammo.btVector3(positions[i + 3], positions[i + 4], positions[i + 5]),
new Ammo.btVector3(positions[i + 6], positions[i + 7], positions[i + 8])];
// Ajouter le triangle à la forme concave
concaveShape.addPoint(triangle[0], false);
concaveShape.addPoint(triangle[1], false);
concaveShape.addPoint(triangle[2], false);
};
console.log("number of positions is : ", positions.length);
};
};
});
console.log("MY Shape : ", concaveShape.getNumVertices());
rbInfo = new Ammo.btRigidBodyConstructionInfo( mass, motionState, concaveShape, localInertia );
body = new Ammo.btRigidBody( rbInfo );
physicsWorld.addRigidBody( body, colGroupPlane, colGroupRedBall );
//addTriangleLines(scene, concaveShape);
await renderer.compileAsync( model, camera, scene );
scene.add( model );
},
// onProgress callback
function ( xhr ) {
console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
},
// onError callback
function ( err ) {
console.error( 'An error happened' );
});
function addTriangleLines(scene, concaveShape) {
const material = new THREE.MeshBasicMaterial({ color: 0xff0000, wireframe: true });
// Boucler à travers chaque point de la forme concave
for (let i = 0; i < concaveShape.getNumVertices(); i += 3) {
console.log(concaveShape.getPoint(i));
// Obtenir les coordonnées des points pour former un triangle
const pointA = concaveShape.points[i];
const pointB = concaveShape.points[i + 1];
const pointC = concaveShape.points[i + 2];
// Créer la géométrie du triangle
const geometry = new THREE.Geometry();
geometry.vertices.push(
new THREE.Vector3(pointA.x(), pointA.y(), pointA.z()),
new THREE.Vector3(pointB.x(), pointB.y(), pointB.z()),
new THREE.Vector3(pointC.x(), pointC.y(), pointC.z())
);
geometry.faces.push(new THREE.Face3(0, 1, 2));
geometry.computeFaceNormals();
// Créer le mesh du triangle et l'ajouter à la scène
const triangleMesh = new THREE.Mesh(geometry, material);
scene.add(triangleMesh);
}
}