OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
StdMeshLoader.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2010-2016, The OpenClonk Team and contributors
5  *
6  * Distributed under the terms of the ISC license; see accompanying file
7  * "COPYING" for details.
8  *
9  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
10  * See accompanying file "TRADEMARK" for details.
11  *
12  * To redistribute this file separately, substitute the full license texts
13  * for the above references.
14  */
15 
16 // A loader for the OGRE .mesh binary file format
17 
18 #include "C4Include.h"
19 
20 #include "lib/StdMeshLoader.h"
21 
22 namespace
23 {
24  // Transpose a StdMeshMatrix. The translate component of
25  // the input matrix must be 0.
26  StdMeshMatrix Transpose(const StdMeshMatrix& matrix)
27  {
28  assert(fabs(matrix(0,3)) < 1e-6);
29  assert(fabs(matrix(1,3)) < 1e-6);
30  assert(fabs(matrix(2,3)) < 1e-6);
31 
32  StdMeshMatrix result;
33 
34  result(0,0) = matrix(0,0);
35  result(0,1) = matrix(1,0);
36  result(0,2) = matrix(2,0);
37  result(0,3) = 0.0f;
38  result(1,0) = matrix(0,1);
39  result(1,1) = matrix(1,1);
40  result(1,2) = matrix(2,1);
41  result(1,3) = 0.0f;
42  result(2,0) = matrix(0,2);
43  result(2,1) = matrix(1,2);
44  result(2,2) = matrix(2,2);
45  result(2,3) = 0.0f;
46 
47  return result;
48  }
49 
50  // Transformation matrix to convert meshes from Ogre to Clonk coordinate system
51  const StdMeshMatrix OgreToClonkMatrix = StdMeshMatrix::Scale(-1.0f, -1.0f, -1.0f) * StdMeshMatrix::Rotate(float(M_PI)/2.0f, 0.0f, 1.0f, 0.0f);
52 
53  const StdMeshMatrix OgreToClonkInverse = StdMeshMatrix::Inverse(OgreToClonkMatrix);
54  const StdMeshMatrix OgreToClonkInverseTranspose = Transpose(OgreToClonkInverse);
55  const float OgreToClonkDeterminant = OgreToClonkMatrix.Determinant();
56 }
57 
58 namespace OgreToClonk
59 {
60 
62 {
63  return OgreToClonkMatrix * vector;
64 }
65 
67 {
68  // TODO: This works only for improper rotations... otherwise it might be better
69  // to write vector as an antisymmetric tensor and do the matrix transform.
70  return OgreToClonkDeterminant * (OgreToClonkMatrix * vector);
71 }
72 
74 {
75  return OgreToClonkInverseTranspose * vector;
76 }
77 
79 {
80  // TODO: Check we didn't introduce shear components
81  StdMeshMatrix scale = StdMeshMatrix::Scale(vector.x, vector.y, vector.z);
82  StdMeshMatrix transformed = OgreToClonkMatrix * scale * OgreToClonkInverse;
83 
84  StdMeshVector result;
85  result.x = transformed(0,0);
86  result.y = transformed(1,1);
87  result.z = transformed(2,2);
88  return result;
89 }
90 
91 StdMeshQuaternion TransformQuaternion(const StdMeshQuaternion& quaternion)
92 {
93  StdMeshVector axis;
94  axis.x = quaternion.x;
95  axis.y = quaternion.y;
96  axis.z = quaternion.z;
97 
98  StdMeshVector transformed = TransformPseudoVector(axis);
99 
100  StdMeshQuaternion result;
101  result.w = quaternion.w;
102  result.x = transformed.x;
103  result.y = transformed.y;
104  result.z = transformed.z;
105 
106  return result;
107 }
108 
110 {
111  StdMeshVector pos, normal;
112  pos.x = vertex.x;
113  pos.y = vertex.y;
114  pos.z = vertex.z;
115  normal.x = vertex.nx;
116  normal.y = vertex.ny;
117  normal.z = vertex.nz;
118 
119  pos = TransformVector(pos);
120  normal = TransformNormalVector(normal);
121 
122  StdSubMesh::Vertex result = vertex;
123  result.x = pos.x;
124  result.y = pos.y;
125  result.z = pos.z;
126  result.nx = normal.x;
127  result.ny = normal.y;
128  result.nz = normal.z;
129 
130  return result;
131 }
132 
133 StdMeshTransformation TransformTransformation(const StdMeshTransformation& trans)
134 {
135  StdMeshTransformation result;
136  result.scale = TransformScaleVector(trans.scale);
137  result.rotate = TransformQuaternion(trans.rotate);
138  result.translate = TransformVector(trans.translate);
139 
140  // Consistency check:
141  /*StdMeshMatrix matrix = StdMeshMatrix::Transform(trans);
142  matrix = OgreToClonk * matrix * OgreToClonkInverse;
143 
144  StdMeshMatrix matrix2 = StdMeshMatrix::Transform(result);
145  for(int i = 0; i < 3; ++i)
146  for(int j = 0; j < 4; ++j)
147  assert(fabs(matrix(i,j) - matrix2(i,j)) < 1e-3);*/
148 
149  return result;
150 }
151 
152 }
StdMeshVector TransformPseudoVector(const StdMeshVector &vector)
StdMeshTransformation TransformTransformation(const StdMeshTransformation &trans)
StdMeshVector TransformNormalVector(const StdMeshVector &vector)
StdMeshVector TransformScaleVector(const StdMeshVector &vector)
StdMeshQuaternion TransformQuaternion(const StdMeshQuaternion &quaternion)
StdMeshVector TransformVector(const StdMeshVector &vector)
StdSubMesh::Vertex TransformVertex(const StdSubMesh::Vertex &vertex)