summaryrefslogtreecommitdiff
path: root/Runtime/Dynamics/NxMeshCreation.cpp
blob: 7ecff3e77d8d5c3b288a07d337f303fe40a66a9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "UnityPrefix.h"

#if ENABLE_PHYSICS
#include "Runtime/Math/Matrix4x4.h"
#include "Runtime/Filters/Mesh/LodMesh.h"
#include "Runtime/Dynamics/ExtractDataFromMesh.h"
#include "External/PhysX/builds/SDKs/Physics/include/NxPhysics.h"
#include "Runtime/Dynamics/PhysicsManager.h"
#include "Runtime/Dynamics/nxmemorystream.h"
#include "External/PhysX/builds/SDKs/Cooking/include/NxCooking.h"
#include "Runtime/Interfaces/IPhysics.h"
#include "Runtime/Profiler/Profiler.h"

PROFILER_INFORMATION(gBakeCollisionMesh, "Mesh.Bake PhysX CollisionData", kProfilerPhysics)
PROFILER_INFORMATION(gBakeCollisionScaledMesh, "Mesh.Bake Scaled Mesh PhysX CollisionData", kProfilerPhysics)

bool CreateNxStreamFromUnityMesh (Mesh* mesh, bool convex, const Matrix4x4f& scalematrix, TransformType transformType, MemoryStream& stream )
{
	dynamic_array<Vector3f> vertices;
	dynamic_array<Vector3f> normals;
	dynamic_array<UInt16> triangles;
	dynamic_array<UInt16> remap;
	if (!ExtractDataFromMesh(*mesh, vertices, triangles, remap))
		return false;

	int vertexCount = vertices.size();
	int	inStride = sizeof(Vector3f);
	if (!IsNoScaleTransform(transformType))
		TransformPoints3x3 (scalematrix, &vertices[0], sizeof(Vector3f), &vertices[0], sizeof(Vector3f), vertexCount);
	
	// PhysX crashes when using only 1 triangle
	// So just duplicate the triangle...
	if (triangles.size() == 3)
	{
		triangles.push_back(triangles[0]);
		triangles.push_back(triangles[1]);
		triangles.push_back(triangles[2]);
	}
	
	if (convex)
	{
		NxConvexMeshDesc desc;
		desc.flags = NX_CF_COMPUTE_CONVEX;
		
		desc.numVertices = vertexCount;
		desc.points = &vertices[0];
		desc.pointStrideBytes = inStride;
				
		return NxCookConvexMesh (desc, stream);
	}
	else
	{
		NxTriangleMeshDesc desc;
		
		desc.numVertices = vertexCount;
		desc.points = &vertices[0];
		desc.pointStrideBytes = inStride;
		
		desc.numTriangles = triangles.size () / 3;
		desc.triangles = &triangles[0];
		desc.triangleStrideBytes = sizeof (triangles[0]) * 3;
		desc.flags = NX_MF_16_BIT_INDICES;

		if (transformType & kOddNegativeScaleTransform)
			desc.flags |= NX_MF_FLIPNORMALS;
		
		return NxCookTriangleMesh (desc, stream);
	}
}

MemoryStream* CreateNxStreamFromUnityMesh(Mesh& meshData, bool convex)
{
	PROFILER_AUTO_THREAD_SAFE(gBakeCollisionMesh, &meshData)
	Matrix4x4f identity; identity.SetIdentity();
	MemoryStream* stream = new MemoryStream (NULL, 0);
	CreateNxStreamFromUnityMesh(&meshData, convex, identity, kNoScaleTransform, *stream);
	return stream;
}

void* CreateNxMeshFromUnityMesh (Mesh* mesh, bool convex, const Matrix4x4f& scalematrix, TransformType transformType )
{
#if ENABLE_PROFILER
	if (IsNoScaleTransform(transformType))
	{	
		PROFILER_BEGIN(gBakeCollisionMesh, mesh)
	}
	else
	{
		PROFILER_BEGIN(gBakeCollisionScaledMesh, mesh)
	}
#endif
	
	MemoryStream stream (NULL, 0);
	
	if (!CreateNxStreamFromUnityMesh(mesh, convex, scalematrix, transformType, stream))
	{
		PROFILER_END
		return NULL;
	}
	
	if (convex)
	{
		NxConvexMesh* nxmesh = GetDynamicsSDK().createConvexMesh (stream);
		PROFILER_END
		return nxmesh;
	}		
	else
	{
		NxTriangleMesh* nxmesh = GetDynamicsSDK().createTriangleMesh (stream);
		PROFILER_END
		return nxmesh;
	}
}

#endif