[SOLVED] Adding collision for mesh/render element

Hi there, I’m trying to add collision element to generated mesh, mesh itself renders but collision appears as a plane PlayCanvas | HTML5 Game Engine

 // Create a mesh with dynamic vertex buffer and static index buffer
    const mesh = new pc.Mesh(app.graphicsDevice);
    this.mesh = mesh;
    
    mesh.clear(true, false);
    this.updateMesh(mesh, true);

    // create material
    const material = new pc.StandardMaterial();
    material.diffuseMap = this.app.assets.find('playcanvas-grey.png').resource;
    material.shininess = 50;
    material.metalness = 0.3;
    material.useMetalness = true;
    material.update();    
    
    // Create the mesh instance
    const meshInstance = new pc.MeshInstance(mesh, material);

    // Create the entity with render component using meshInstances
    const entity = this.entity;
    entity.addComponent("render", {
        meshInstances: [meshInstance]
    });

        this.entity.addComponent('collision', {
        type: 'mesh'
    });

        // We still have to create a model resource to create a runtime
    // collision mesh
    var node = new pc.GraphNode();
    var collisionModel = new pc.Model();
    collisionModel.graph = node;
    collisionModel.meshInstances.push(meshInstance);

    this.entity.collision.model = collisionModel;

    this.entity.addComponent('rigidbody', {
        friction: 0.5,
        type: 'static'
    });

Hi @Newbie_Coder,

Hmm, that’s quite strange, you can use the following extension to get a better understanding of what collision shapes are created:

I’m curious myself why it behaves like a plane, most likely the scale is wrong or something like that.

One thing you can try, similar to the terrain generation example, try creating a separate mesh instance for collision model instead of reusing the render mesh instance. Not sure if it makes a difference though:

https://developer.playcanvas.com/en/tutorials/terrain-generation/

1 Like

Hi, I’ve tried to add separate mesh instance, changed scales/deform factors, same results unfortunately.

// Create a mesh with dynamic vertex buffer and static index buffer
    const mesh = new pc.Mesh(app.graphicsDevice);
    this.mesh = mesh;
    
    mesh.clear(true, false);
    this.updateMesh(mesh, true);

    // create material
    const material = new pc.StandardMaterial();
    material.diffuseMap = this.app.assets.find('playcanvas-grey.png').resource;
    material.shininess = 50;
    material.metalness = 0.3;
    material.useMetalness = true;
    material.update();    
    

    // Create the entity with render component using meshInstances
      this.entity.addComponent('render', {
        meshInstances: [new pc.MeshInstance(mesh, material)]
    });

      this.entity.addComponent('collision', {
        type: 'mesh'
    });

      // We still have to create a model resource to create a runtime
    // collision mesh
    var node = new pc.GraphNode();
    var meshInstance = new pc.MeshInstance(node, mesh, material);
    var collisionModel = new pc.Model();
    collisionModel.graph = node;
    collisionModel.meshInstances.push(meshInstance);

    this.entity.collision.model = collisionModel;

    this.entity.addComponent('rigidbody', {
        friction: 0.5,
        type: 'static'
    });

2nd solution

    var node = new pc.GraphNode();
     var meshInstance = new pc.MeshInstance(node, mesh, material);
    var model = new pc.Model();
    model.graph = node;
    model.meshInstances.push(meshInstance);

     this.entity.addComponent('model');
    this.entity.model.model = model;

    this.entity.addComponent('collision', {
        type: 'mesh'
    });
    this.entity.collision.model = model;

    this.entity.addComponent('rigidbody', {
        friction: 0.5,
        type: 'static'
    });

No luck either

Try using Ammo Debug Draw I shared above.


https://playcanvas.com/editor/scene/1491820

I have tried to add a var meshCreated to check if mesh has been generated and only then create meshInstance etc, haven’t helped too

Seems like public example wasn’t supposed to work the way I want, so I’ve fully edited the script to work upon initialize only, now the question is, what are those ‘Other primitives’ or is it just debug draw?

A question for @Leonidas, How do I generate a random seed by (seedrandom.js) that is always less than X? Thank you for your continuous help

Hey, other primitives are coming from the debug lines you are rendering for physics.

Regrading seed random any regular math random between min and max values will work e.g. this:

Just replace Math.random with your own seed random rng() method.

2 Likes

Thank you again, I have another question… :grinning:
I’m trying to remove all flats from mesh, what else apart positions is needed in order to achieve that?

noFlatPositions = [];

// to loop through coordinate values
for (var i2a = 0; i2a < this.positions.length; i2a+=3) {
    var x = this.positions[i2a];
    var y = this.positions[i2a+1];
    var z = this.positions[i2a+2];   
    //var pos = (x + y + z);   
    if (y > 0) {
   noFlatPositions.push(x, y, z);
    }
} 
var newPositions = new Float32Array(noFlatPositions);

Current state: Failing to generate mesh ‘Vertex buffer is not big enough for the draw call’

Hi @Newbie_Coder,

If you have indexed geometry, you should be removing indices too, as you loop and remove positions.

You’re quick, working on it

I’m facing another problem, seems like one of the meshInstances are getting twice the distance from other one, at the pic below plane is located at 50,0,0,


setting location to 100,0,0

I have tried changing graph position and it doesn’t move
The code:

// Create the mesh instance
    const meshInstance = new pc.MeshInstance(this.mesh, material);

    // Create the entity with render component using meshInstances
    this.entity.addComponent("render", {
        meshInstances: [meshInstance]
    });

        this.entity.addComponent('collision', {
        type: 'mesh'
    });

        // We still have to create a model resource to create a runtime
    // collision mesh
    var node = new pc.GraphNode();
    var collisionModel = new pc.Model();
    collisionModel.graph = node;
    collisionModel.meshInstances.push(meshInstance);

    this.entity.collision.model = collisionModel;

    this.entity.addComponent('rigidbody', {
        friction: 0.5,
        type: 'static'
    });

I have solved the issue by adding a collision element to a new child entity insead

 // Create the mesh instance
    const meshInstance = new pc.MeshInstance(this.mesh, material);

    // Create the entity with render component using meshInstances
    this.entity.addComponent("render", {
        meshInstances: [meshInstance]
    });


    var test = new pc.Entity(); // Create an Entity


    this.entity.addChild(test);
    colpos = this.entity.getPosition();
    test.setPosition(colpos.x-colpos.x, colpos.y-colpos.y, colpos.z-colpos.z);

        test.addComponent('collision', {
        type: 'mesh'
    });

        // We still have to create a model resource to create a runtime
    // collision mesh
    var node = new pc.GraphNode();
    var collisionModel = new pc.Model();
    collisionModel.graph = node;
    collisionModel.meshInstances.push(meshInstance);

   test.collision.model = collisionModel;

   test.addComponent('rigidbody', {
        friction: 0.5,
        type: 'static'
    });

Thank you Leonidas, I owe you a cup of coffe :grin:
I want to share some results, mesh resolution is quite low (60) thus generating around 20,000 triangles, scale 100x100, the most amazing thing is a string seed

PlayCanvas


Javascript

Leonidas

Pillow

We can mark this as solved, I’m creating a new topic regarding materias soon

1 Like

Nice, very well done, I love seeded terrains! :innocent:

1 Like