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 #include "lib/StdMeshLoader.h"
20 
21 namespace
22 {
23  // Transpose a StdMeshMatrix. The translate component of
24  // the input matrix must be 0.
25  StdMeshMatrix Transpose(const StdMeshMatrix& matrix)
26  {
27  assert(fabs(matrix(0,3)) < 1e-6);
28  assert(fabs(matrix(1,3)) < 1e-6);
29  assert(fabs(matrix(2,3)) < 1e-6);
30 
31  StdMeshMatrix result;
32 
33  result(0,0) = matrix(0,0);
34  result(0,1) = matrix(1,0);
35  result(0,2) = matrix(2,0);
36  result(0,3) = 0.0f;
37  result(1,0) = matrix(0,1);
38  result(1,1) = matrix(1,1);
39  result(1,2) = matrix(2,1);
40  result(1,3) = 0.0f;
41  result(2,0) = matrix(0,2);
42  result(2,1) = matrix(1,2);
43  result(2,2) = matrix(2,2);
44  result(2,3) = 0.0f;
45 
46  return result;
47  }
48 
49  // Transformation matrix to convert meshes from Ogre to Clonk coordinate system
50  const StdMeshMatrix OgreToClonkMatrix = StdMeshMatrix::Scale(-1.0f, -1.0f, -1.0f) * StdMeshMatrix::Rotate(float(M_PI)/2.0f, 0.0f, 1.0f, 0.0f);
51 
52  const StdMeshMatrix OgreToClonkInverse = StdMeshMatrix::Inverse(OgreToClonkMatrix);
53  const StdMeshMatrix OgreToClonkInverseTranspose = Transpose(OgreToClonkInverse);
54  const float OgreToClonkDeterminant = OgreToClonkMatrix.Determinant();
55 }
56 
57 namespace OgreToClonk
58 {
59 
61 {
62  return OgreToClonkMatrix * vector;
63 }
64 
66 {
67  // TODO: This works only for improper rotations... otherwise it might be better
68  // to write vector as an antisymmetric tensor and do the matrix transform.
69  return OgreToClonkDeterminant * (OgreToClonkMatrix * vector);
70 }
71 
73 {
74  return OgreToClonkInverseTranspose * vector;
75 }
76 
78 {
79  // TODO: Check we didn't introduce shear components
80  StdMeshMatrix scale = StdMeshMatrix::Scale(vector.x, vector.y, vector.z);
81  StdMeshMatrix transformed = OgreToClonkMatrix * scale * OgreToClonkInverse;
82 
83  StdMeshVector result;
84  result.x = transformed(0,0);
85  result.y = transformed(1,1);
86  result.z = transformed(2,2);
87  return result;
88 }
89 
90 StdMeshQuaternion TransformQuaternion(const StdMeshQuaternion& quaternion)
91 {
92  StdMeshVector axis;
93  axis.x = quaternion.x;
94  axis.y = quaternion.y;
95  axis.z = quaternion.z;
96 
97  StdMeshVector transformed = TransformPseudoVector(axis);
98 
99  StdMeshQuaternion result;
100  result.w = quaternion.w;
101  result.x = transformed.x;
102  result.y = transformed.y;
103  result.z = transformed.z;
104 
105  return result;
106 }
107 
109 {
110  StdMeshVector pos, normal;
111  pos.x = vertex.x;
112  pos.y = vertex.y;
113  pos.z = vertex.z;
114  normal.x = vertex.nx;
115  normal.y = vertex.ny;
116  normal.z = vertex.nz;
117 
118  pos = TransformVector(pos);
119  normal = TransformNormalVector(normal);
120 
121  StdSubMesh::Vertex result = vertex;
122  result.x = pos.x;
123  result.y = pos.y;
124  result.z = pos.z;
125  result.nx = normal.x;
126  result.ny = normal.y;
127  result.nz = normal.z;
128 
129  return result;
130 }
131 
132 StdMeshTransformation TransformTransformation(const StdMeshTransformation& trans)
133 {
134  StdMeshTransformation result;
135  result.scale = TransformScaleVector(trans.scale);
136  result.rotate = TransformQuaternion(trans.rotate);
137  result.translate = TransformVector(trans.translate);
138 
139  // Consistency check:
140  /*StdMeshMatrix matrix = StdMeshMatrix::Transform(trans);
141  matrix = OgreToClonk * matrix * OgreToClonkInverse;
142 
143  StdMeshMatrix matrix2 = StdMeshMatrix::Transform(result);
144  for(int i = 0; i < 3; ++i)
145  for(int j = 0; j < 4; ++j)
146  assert(fabs(matrix(i,j) - matrix2(i,j)) < 1e-3);*/
147 
148  return result;
149 }
150 
151 }
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)