I am trying to use the lamborghini.glb model in the playcanvas react docs as a test model to test the mesh collision physics, but i can manage to pull it of.
I have no experience with React, but from what I can see, you set the rigidbody type to static. If this is a moving object, I would expect a dynamic rigidbody instead (or kinematic if you don’t want to use physics).
Also, be aware that mesh-to-mesh collision is not supported.
I am not familiar with react, but maybe @Mark_Lundin can give advice.
As for collision mesh - for a static object you want to use mesh as a collision shape type. It will collide with dynamic convex shapes, like capsules, spheres, etc.
For a dynamic object, you can use convex hull as a collision shape type. This will allow it to become dynamic object as well. It is more expensive than a static mesh, though, so don’t use it, unless you really have to.
Hi @LeXXik@Mark_Lundin !!
I have been trying to solve the mesh collision problem but it has been impossible.
This is a simplified version of the code i want to achieve where a static mesh is used as a collider for a falling object (collision type box in this case).
The falling box keeps going through the static mesh, but collides correctly with the ground (also collision type box) under it.
Please, help me figure out how the mesh collision works, I will heavily appreciate it
Also, i think the wireframe renderstyle has problems with the type asset in the render component. Because it works perfectly fine with a type box render.
import React from 'react';
import { Application, Entity } from '@playcanvas/react';
import { useModel } from '@playcanvas/react/hooks';
import { Camera, Render, Light, Collision, RigidBody } from '@playcanvas/react/components';
import { OrbitControls } from '@playcanvas/react/scripts';
import { FILLMODE_FILL_WINDOW, RESOLUTION_AUTO } from 'playcanvas';
export function ModelViewer() {
const { asset } = useModel("lamborghini_vision_gt.glb");
// If the asset is not loaded, return null
if (!asset) return null;
// If the asset is loaded, render it
return (
<Entity name="mesh" position={[0, 5, 0.5]}>
<Render type='asset' asset={asset} renderStyle={1}/>;
<Collision type='asset' asset={asset} />
<RigidBody type="static" />
</Entity>
);
}
export default function App() {
return (
<Application
fillMode={FILLMODE_FILL_WINDOW}
resolutionMode={RESOLUTION_AUTO}
usePhysics
>
<Entity name='camera' position={[0, 10, 25]}>
<Camera />
<OrbitControls />
</Entity>
<Entity name='light' rotation={[45, -45, 45]}>
<Light type='directional' />
</Entity>
<Entity name='ground' scale={[20, 1, 20]}>
<Render type="box" />
<Collision type="box" halfExtents={[10, 0.5, 10]} />
<RigidBody type="static" />
</Entity>
<Entity name='fallingBox' position={[0, 10, 0]}>
<Render type="box" />
<Collision type="box" />
<RigidBody type="dynamic" mass={50} />
</Entity>
<ModelViewer />
</Application>
);
}
Same problem, can not make the mesh collider work using react, brower console keeps telling me: [PlayCanvas React]: Unknown props in “.”
The following props are invalid and will be ignored: “asset”
Hey @Jorgix and @JazzenChen. So the issue here is that loaded GLB’s are a sub hierarchy of entities. So we need a better API to map these to Collision or RigidBody components. This is something I’m actively working on.
As a workaround for the time being, you would need to manually add these in a useEffect hook once the asset is loaded.
Thanks for the answer and for your work.
I would really appreciate if you have an example of code of the workaround to see excatly how to manage the issue.
I have been trying to figure out the workaround, but its been impossible for me to make it work.
Could you please share if you have an example of code that uses what you say.
Hi @Mark_Lundin, sorry to bother you, but its been impossible for me to make it work.
With that implementation the model fallas until it reaches trhe ground and it gets dissolved in each piece. Also if the type is set to static the collision doesnt work at all.
This is my actual code:
export function ModelViewer() {
const { asset } = useModel("lamborghini_vision_gt.glb");
const entityRef = useRef();
const app = useApp();
useEffect(() => {
if (!entityRef.current || !asset) return;
// select all render components
const components = entityRef.current.findComponents('render');
// add some imperative logic to add components to each entity with a render component
components.forEach((component) => {
if (component.meshInstances.length > 0) {
const meshInstance = component.meshInstances[0];
const model = new Model();
model.graph = meshInstance.node;
model.meshInstances.push(meshInstance);
component.entity.addComponent('collision', {
type: 'mesh',
model: model,
convexHull: true
});
component.entity.addComponent('rigidbody', {
type: 'dynamic',
mass: 50,
restitution: 0.5
});
}
});
}, [asset, app]);
// If the asset is not loaded, return null
if (!asset) return null;
// If the asset is loaded, render it
return (
<Entity name="mesh" position={[0, 5, 0.5]} ref={entityRef}>
<Render type='asset' asset={asset} renderStyle={1}/>
</Entity>
);
}