void BuiltinResources::generateMeshes() { SPtr<VertexDataDesc> vertexDesc = bs_shared_ptr_new<VertexDataDesc>(); vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION); vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD); vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL); vertexDesc->addVertElem(VET_FLOAT4, VES_TANGENT); vertexDesc->addVertElem(VET_COLOR, VES_COLOR); UINT32 boxNumVertices = 0; UINT32 boxNumIndices = 0; ShapeMeshes3D::getNumElementsAABox(boxNumVertices, boxNumIndices); SPtr<MeshData> boxMeshData = MeshData::create(boxNumVertices, boxNumIndices, vertexDesc); AABox box(Vector3(-0.5f, -0.5f, -0.5f), Vector3(0.5f, 0.5f, 0.5f)); ShapeMeshes3D::solidAABox(box, boxMeshData, 0, 0); SPtr<Mesh> boxMesh = Mesh::_createPtr(RendererMeshData::convert(boxMeshData)); UINT32 sphereNumVertices = 0; UINT32 sphereNumIndices = 0; ShapeMeshes3D::getNumElementsSphere(3, sphereNumVertices, sphereNumIndices); SPtr<MeshData> sphereMeshData = bs_shared_ptr_new<MeshData>(sphereNumVertices, sphereNumIndices, vertexDesc); ShapeMeshes3D::solidSphere(Sphere(Vector3::ZERO, 1.0f), sphereMeshData, 0, 0, 3); SPtr<Mesh> sphereMesh = Mesh::_createPtr(RendererMeshData::convert(sphereMeshData)); UINT32 coneNumVertices = 0; UINT32 coneNumIndices = 0; ShapeMeshes3D::getNumElementsCone(10, coneNumVertices, coneNumIndices); SPtr<MeshData> coneMeshData = bs_shared_ptr_new<MeshData>(coneNumVertices, coneNumIndices, vertexDesc); ShapeMeshes3D::solidCone(Vector3::ZERO, Vector3::UNIT_Y, 1.0f, 1.0f, Vector2::ONE, coneMeshData, 0, 0); SPtr<Mesh> coneMesh = Mesh::_createPtr(RendererMeshData::convert(coneMeshData)); UINT32 cylinderNumVertices = 0; UINT32 cylinderNumIndices = 0; ShapeMeshes3D::getNumElementsCylinder(10, cylinderNumVertices, cylinderNumIndices); SPtr<MeshData> cylinderMeshData = bs_shared_ptr_new<MeshData>(cylinderNumVertices, cylinderNumIndices, vertexDesc); ShapeMeshes3D::solidCylinder(Vector3::ZERO, Vector3::UNIT_Y, 1.0f, 1.0f, Vector2::ONE, cylinderMeshData, 0, 0); SPtr<Mesh> cylinderMesh = Mesh::_createPtr(RendererMeshData::convert(cylinderMeshData)); UINT32 quadNumVertices = 8; UINT32 quadNumIndices = 12; ShapeMeshes3D::getNumElementsQuad(quadNumVertices, quadNumIndices); SPtr<MeshData> quadMeshData = bs_shared_ptr_new<MeshData>(quadNumVertices, quadNumIndices, vertexDesc); std::array<Vector3, 2> axes = {{ Vector3::UNIT_X, Vector3::UNIT_Z }}; std::array<float, 2> sizes = {{ 1.0f, 1.0f }}; Rect3 rect(Vector3::ZERO, axes, sizes); ShapeMeshes3D::solidQuad(rect, quadMeshData, 0, 0); SPtr<Mesh> quadMesh = Mesh::_createPtr(RendererMeshData::convert(quadMeshData)); UINT32 discNumVertices = 0; UINT32 discNumIndices = 0; ShapeMeshes3D::getNumElementsDisc(10, discNumVertices, discNumIndices); SPtr<MeshData> discMeshData = bs_shared_ptr_new<MeshData>(discNumVertices, discNumIndices, vertexDesc); ShapeMeshes3D::solidDisc(Vector3::ZERO, 1.0f, Vector3::UNIT_Y, discMeshData, 0, 0); SPtr<Mesh> discMesh = Mesh::_createPtr(RendererMeshData::convert(discMeshData)); // Save all meshes Path outputDir = mEngineMeshFolder; auto saveMesh = [&](const Path& path, const SPtr<Mesh>& mesh, const String& uuid) { HResource meshResource = gResources()._createResourceHandle(mesh, UUID(uuid)); gResources().save(meshResource, path, true); mResourceManifest->registerResource(meshResource.getUUID(), path); }; Path boxPath = outputDir + MeshBoxFile; saveMesh(boxPath, boxMesh, "bc1d20ca-7fe6-489b-8b5c-dbf798badc95"); Path spherePath = outputDir + MeshSphereFile; saveMesh(spherePath, sphereMesh, "040642f3-04d6-419e-9dba-f7824161c205"); Path conePath = outputDir + MeshConeFile; saveMesh(conePath, coneMesh, "b8cf6db5-1736-47ac-852f-82ecd88b4d46"); Path cylinderPath = outputDir + MeshCylinderFile; saveMesh(cylinderPath, cylinderMesh, "e6b2b797-4e72-7e49-61ba-4e7275bd561d"); Path quadPath = outputDir + MeshQuadFile; saveMesh(quadPath, quadMesh, "06592bf3-f82a-472e-a034-26a98225fbe1"); Path discPath = outputDir + MeshDiscFile; saveMesh(discPath, discMesh, "6f496313-344a-495c-83e8-152e3053c52d"); }
SPtr<MeshData> FPhysXMesh::getMeshData() const { SPtr<VertexDataDesc> vertexDesc = VertexDataDesc::create(); vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION); if (mConvexMesh == nullptr && mTriangleMesh == nullptr) return MeshData::create(0, 0, vertexDesc); UINT32 numVertices = 0; UINT32 numIndices = 0; if(mConvexMesh != nullptr) { numVertices = mConvexMesh->getNbVertices(); UINT32 numPolygons = mConvexMesh->getNbPolygons(); for (UINT32 i = 0; i < numPolygons; i++) { PxHullPolygon face; bool status = mConvexMesh->getPolygonData(i, face); assert(status); numIndices += (face.mNbVerts - 2) * 3; } } else // Triangle { numVertices = mTriangleMesh->getNbVertices(); numIndices = mTriangleMesh->getNbTriangles() * 3; } SPtr<MeshData> meshData = MeshData::create(numVertices, numIndices, vertexDesc); auto posIter = meshData->getVec3DataIter(VES_POSITION); UINT32* outIndices = meshData->getIndices32(); if (mConvexMesh != nullptr) { const PxVec3* convexVertices = mConvexMesh->getVertices(); const UINT8* convexIndices = mConvexMesh->getIndexBuffer(); for (UINT32 i = 0; i < numVertices; i++) posIter.addValue(fromPxVector(convexVertices[i])); UINT32 numPolygons = mConvexMesh->getNbPolygons(); for (UINT32 i = 0; i < numPolygons; i++) { PxHullPolygon face; bool status = mConvexMesh->getPolygonData(i, face); assert(status); const PxU8* faceIndices = convexIndices + face.mIndexBase; for (UINT32 j = 2; j < face.mNbVerts; j++) { *outIndices++ = faceIndices[0]; *outIndices++ = faceIndices[j]; *outIndices++ = faceIndices[j - 1]; } } } else { const PxVec3* vertices = mTriangleMesh->getVertices(); for (UINT32 i = 0; i < numVertices; i++) posIter.addValue(fromPxVector(vertices[i])); if(mTriangleMesh->getTriangleMeshFlags() & PxTriangleMeshFlag::e16_BIT_INDICES) { const UINT16* indices = (const UINT16*)mTriangleMesh->getTriangles(); UINT32 numTriangles = numIndices / 3; for (UINT32 i = 0; i < numTriangles; i++) { // Flip triangles as PhysX keeps them opposite to what Banshee expects outIndices[i * 3 + 0] = (UINT32)indices[i * 3 + 0]; outIndices[i * 3 + 1] = (UINT32)indices[i * 3 + 2]; outIndices[i * 3 + 2] = (UINT32)indices[i * 3 + 1]; } } else { const UINT32* indices = (const UINT32*)mTriangleMesh->getTriangles(); UINT32 numTriangles = numIndices / 3; for (UINT32 i = 0; i < numTriangles; i++) { // Flip triangles as PhysX keeps them opposite to what Banshee expects outIndices[i * 3 + 0] = indices[i * 3 + 0]; outIndices[i * 3 + 1] = indices[i * 3 + 2]; outIndices[i * 3 + 2] = indices[i * 3 + 1]; } } } return meshData; }