diff --git a/core/entity.jai b/core/entity.jai index 63a2e6c..dcfa014 100644 --- a/core/entity.jai +++ b/core/entity.jai @@ -55,6 +55,7 @@ MAX_CHILDREN :: 16; SPHERE; BOX; CAPSULE; + MESH; } Physics_Lock :: enum_flags u8 { diff --git a/physics/physx.jai b/physics/physx.jai index ff53e7f..386a47e 100644 --- a/physics/physx.jai +++ b/physics/physx.jai @@ -43,6 +43,8 @@ init_physx :: () { tolerance_scale.speed = 10; physics = PhysX.PxCreatePhysics(PhysX.PX_PHYSICS_VERSION, foundation, *tolerance_scale, true, pvd, null); + cooking_params = PhysX.PxCookingParams_new(*tolerance_scale); + dispatcher = PhysX.PxDefaultCpuDispatcherCreate(2); material = PhysX.PxPhysics_createMaterial(physics, 0.0, 0.0, 0.6); @@ -201,6 +203,58 @@ create_physx_actor :: (e: *Entity) { case .CAPSULE; { geo = PhysX.PxCapsuleGeometry_new(e.physics.capsule.radius, e.physics.capsule.half_height-e.physics.capsule.radius); } + case .MESH; { + if e.flags & .RENDERABLE { + points : [..] Vector3; + points.allocator = temp; + indices : [..] u32; + indices.allocator = temp; + + model := get_model_by_handle(e.renderable.model); + + for node, node_index: model.nodes { + index_start : u32 = xx indices.count; + render_data := e.renderable.nodes[node_index]; + + success, inv_matrix := inverse(e.transform.model_matrix); + // We need to undo the local to world part of every world matrix + matrix := inv_matrix * render_data.transform.world_matrix; + + if node.meshes.count > 0 { + for m, mi: node.meshes { + mesh := parray_get(*engine.renderer.meshes, m); + for v: mesh.positions { + array_add(*points, transform_position(v, matrix)); + } + + for i: mesh.indices { + array_add(*indices, index_start + i); + } + } + } + } + mesh_desc := PhysX.PxTriangleMeshDesc_new(); + mesh_desc.points.count = xx points.count; + mesh_desc.points.stride = size_of(Vector3); + mesh_desc.points.data = points.data; + + mesh_desc.triangles.count = cast(u32)(indices.count / 3); + mesh_desc.triangles.stride = 3 * size_of(u32); + mesh_desc.triangles.data = indices.data; + + if PhysX.PxValidateTriangleMesh(*cooking_params, *mesh_desc) { + assert(false); + } + + stream : PhysX.PxOutputStream; + callback := PhysX.PxGetStandaloneInsertionCallback(); + //read_buffer : PhysX.PxDefaultMemoryInputData_new(; + cond : s32; + mesh := PhysX.PxCreateTriangleMesh(*cooking_params, *mesh_desc, callback, null); + scale := PhysX.PxMeshScale_new(*e.transform.scale); + geo = PhysX.PxTriangleMeshGeometry_new(mesh, *scale, 0); + } + } } shape := PhysX.PxPhysics_createShape(physics, geo, material, false, ifx e.physics.trigger then PHYSX_DEFAULT_TRIGGER_SHAPE_FLAGS else PHYSX_DEFAULT_SIMULATION_SHAPE_FLAGS); @@ -246,6 +300,7 @@ PhysX :: #import "PhysX"; #scope_file physics : *PhysX.PxPhysics; +cooking_params: PhysX.PxCookingParams; material : *PhysX.PxMaterial; default_allocator : PhysX.PxAllocatorCallback; default_error_callback : PhysX.PxErrorCallback;