summaryrefslogtreecommitdiff
path: root/Runtime/Filters/Mesh/MeshUtility.cpp
blob: 75d8e7ff25d61f69a87cb5bc03324bb91f72d96f (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
#include "UnityPrefix.h"
#include "MeshUtility.h"
#include "Runtime/Geometry/Plane.h"
#include "Mesh.h"

using namespace std;

void CalculateNormals (StrideIterator<Vector3f> verts, const UInt32* indices, int vertexCount, int triangleCount, StrideIterator<Vector3f> outNormals)
{
	std::fill_n (outNormals, vertexCount, Vector3f(0,0,0));
	
	// Add normals from faces
	int idx = 0;
	for( int i = 0; i < triangleCount; ++i )
	{
		UInt32 index0 = indices[idx+0];
		UInt32 index1 = indices[idx+1];
		UInt32 index2 = indices[idx+2];
		Vector3f faceNormal = CalcRawNormalFromTriangle( verts[index0], verts[index1], verts[index2] );
		outNormals[index0] += faceNormal;
		outNormals[index1] += faceNormal;
		outNormals[index2] += faceNormal;
		idx += 3;
	}

	// Normalize
	for (StrideIterator<Vector3f> end = outNormals + vertexCount; outNormals != end; ++outNormals )
	{
		*outNormals = NormalizeFast (*outNormals);
	}
}


float CalculateSurfaceArea (
	const Matrix4x4f& objectToWorld,
	const Mesh::TemporaryIndexContainer& triangles,
	dynamic_array<Vector3f>& vertices)
{
	// transform the vertices to world space,
	// do it in place since they are a copy
	for (int i = 0; i < vertices.size (); i++)
		vertices[i] = objectToWorld.MultiplyPoint3 (vertices[i]);

	// calculate the area
	float cachedSurfaceArea = 0;
	for (int i = 0; i < triangles.size () / 3; i++)
	{	
		DebugAssert (triangles[3 * i] < vertices.size ());
		DebugAssert (triangles[3 * i + 1] < vertices.size ());
		DebugAssert (triangles[3 * i + 2] < vertices.size ());
		Vector3f a = vertices[triangles[3 * i]];
		Vector3f b = vertices[triangles[3 * i + 1]];
		Vector3f c = vertices[triangles[3 * i + 2]];
		cachedSurfaceArea += Magnitude (Cross (b - a, c - a)) * 0.5f;
	}

	return cachedSurfaceArea;
}