diff options
Diffstat (limited to 'libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp')
-rw-r--r-- | libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp b/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp new file mode 100644 index 0000000..e715055 --- /dev/null +++ b/libraries/ode-0.9/OPCODE/Ice/IcePoint.cpp | |||
@@ -0,0 +1,193 @@ | |||
1 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
2 | /** | ||
3 | * Contains code for 3D vectors. | ||
4 | * \file IcePoint.cpp | ||
5 | * \author Pierre Terdiman | ||
6 | * \date April, 4, 2000 | ||
7 | */ | ||
8 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
9 | |||
10 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
11 | /** | ||
12 | * 3D point. | ||
13 | * | ||
14 | * The name is "Point" instead of "Vector" since a vector is N-dimensional, whereas a point is an implicit "vector of dimension 3". | ||
15 | * So the choice was between "Point" and "Vector3", the first one looked better (IMHO). | ||
16 | * | ||
17 | * Some people, then, use a typedef to handle both points & vectors using the same class: typedef Point Vector3; | ||
18 | * This is bad since it opens the door to a lot of confusion while reading the code. I know it may sounds weird but check this out: | ||
19 | * | ||
20 | * \code | ||
21 | * Point P0,P1 = some 3D points; | ||
22 | * Point Delta = P1 - P0; | ||
23 | * \endcode | ||
24 | * | ||
25 | * This compiles fine, although you should have written: | ||
26 | * | ||
27 | * \code | ||
28 | * Point P0,P1 = some 3D points; | ||
29 | * Vector3 Delta = P1 - P0; | ||
30 | * \endcode | ||
31 | * | ||
32 | * Subtle things like this are not caught at compile-time, and when you find one in the code, you never know whether it's a mistake | ||
33 | * from the author or something you don't get. | ||
34 | * | ||
35 | * One way to handle it at compile-time would be to use different classes for Point & Vector3, only overloading operator "-" for vectors. | ||
36 | * But then, you get a lot of redundant code in thoses classes, and basically it's really a lot of useless work. | ||
37 | * | ||
38 | * Another way would be to use homogeneous points: w=1 for points, w=0 for vectors. That's why the HPoint class exists. Now, to store | ||
39 | * your model's vertices and in most cases, you really want to use Points to save ram. | ||
40 | * | ||
41 | * \class Point | ||
42 | * \author Pierre Terdiman | ||
43 | * \version 1.0 | ||
44 | */ | ||
45 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
46 | |||
47 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
48 | // Precompiled Header | ||
49 | #include "Stdafx.h" | ||
50 | |||
51 | using namespace IceMaths; | ||
52 | |||
53 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
54 | /** | ||
55 | * Creates a positive unit random vector. | ||
56 | * \return Self-reference | ||
57 | */ | ||
58 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
59 | Point& Point::PositiveUnitRandomVector() | ||
60 | { | ||
61 | x = UnitRandomFloat(); | ||
62 | y = UnitRandomFloat(); | ||
63 | z = UnitRandomFloat(); | ||
64 | Normalize(); | ||
65 | return *this; | ||
66 | } | ||
67 | |||
68 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
69 | /** | ||
70 | * Creates a unit random vector. | ||
71 | * \return Self-reference | ||
72 | */ | ||
73 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | ||
74 | Point& Point::UnitRandomVector() | ||
75 | { | ||
76 | x = UnitRandomFloat() - 0.5f; | ||
77 | y = UnitRandomFloat() - 0.5f; | ||
78 | z = UnitRandomFloat() - 0.5f; | ||
79 | Normalize(); | ||
80 | return *this; | ||
81 | } | ||
82 | |||
83 | // Cast operator | ||
84 | // WARNING: not inlined | ||
85 | Point::operator HPoint() const { return HPoint(x, y, z, 0.0f); } | ||
86 | |||
87 | Point& Point::Refract(const Point& eye, const Point& n, float refractindex, Point& refracted) | ||
88 | { | ||
89 | // Point EyePt = eye position | ||
90 | // Point p = current vertex | ||
91 | // Point n = vertex normal | ||
92 | // Point rv = refracted vector | ||
93 | // Eye vector - doesn't need to be normalized | ||
94 | Point Env; | ||
95 | Env.x = eye.x - x; | ||
96 | Env.y = eye.y - y; | ||
97 | Env.z = eye.z - z; | ||
98 | |||
99 | float NDotE = n|Env; | ||
100 | float NDotN = n|n; | ||
101 | NDotE /= refractindex; | ||
102 | |||
103 | // Refracted vector | ||
104 | refracted = n*NDotE - Env*NDotN; | ||
105 | |||
106 | return *this; | ||
107 | } | ||
108 | |||
109 | Point& Point::ProjectToPlane(const Plane& p) | ||
110 | { | ||
111 | *this-= (p.d + (*this|p.n))*p.n; | ||
112 | return *this; | ||
113 | } | ||
114 | |||
115 | void Point::ProjectToScreen(float halfrenderwidth, float halfrenderheight, const Matrix4x4& mat, HPoint& projected) const | ||
116 | { | ||
117 | projected = HPoint(x, y, z, 1.0f) * mat; | ||
118 | projected.w = 1.0f / projected.w; | ||
119 | |||
120 | projected.x*=projected.w; | ||
121 | projected.y*=projected.w; | ||
122 | projected.z*=projected.w; | ||
123 | |||
124 | projected.x *= halfrenderwidth; projected.x += halfrenderwidth; | ||
125 | projected.y *= -halfrenderheight; projected.y += halfrenderheight; | ||
126 | } | ||
127 | |||
128 | void Point::SetNotUsed() | ||
129 | { | ||
130 | // We use a particular integer pattern : 0xffffffff everywhere. This is a NAN. | ||
131 | IR(x) = 0xffffffff; | ||
132 | IR(y) = 0xffffffff; | ||
133 | IR(z) = 0xffffffff; | ||
134 | } | ||
135 | |||
136 | BOOL Point::IsNotUsed() const | ||
137 | { | ||
138 | if(IR(x)!=0xffffffff) return FALSE; | ||
139 | if(IR(y)!=0xffffffff) return FALSE; | ||
140 | if(IR(z)!=0xffffffff) return FALSE; | ||
141 | return TRUE; | ||
142 | } | ||
143 | |||
144 | Point& Point::Mult(const Matrix3x3& mat, const Point& a) | ||
145 | { | ||
146 | x = a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2]; | ||
147 | y = a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2]; | ||
148 | z = a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2]; | ||
149 | return *this; | ||
150 | } | ||
151 | |||
152 | Point& Point::Mult2(const Matrix3x3& mat1, const Point& a1, const Matrix3x3& mat2, const Point& a2) | ||
153 | { | ||
154 | x = a1.x * mat1.m[0][0] + a1.y * mat1.m[0][1] + a1.z * mat1.m[0][2] + a2.x * mat2.m[0][0] + a2.y * mat2.m[0][1] + a2.z * mat2.m[0][2]; | ||
155 | y = a1.x * mat1.m[1][0] + a1.y * mat1.m[1][1] + a1.z * mat1.m[1][2] + a2.x * mat2.m[1][0] + a2.y * mat2.m[1][1] + a2.z * mat2.m[1][2]; | ||
156 | z = a1.x * mat1.m[2][0] + a1.y * mat1.m[2][1] + a1.z * mat1.m[2][2] + a2.x * mat2.m[2][0] + a2.y * mat2.m[2][1] + a2.z * mat2.m[2][2]; | ||
157 | return *this; | ||
158 | } | ||
159 | |||
160 | Point& Point::Mac(const Matrix3x3& mat, const Point& a) | ||
161 | { | ||
162 | x += a.x * mat.m[0][0] + a.y * mat.m[0][1] + a.z * mat.m[0][2]; | ||
163 | y += a.x * mat.m[1][0] + a.y * mat.m[1][1] + a.z * mat.m[1][2]; | ||
164 | z += a.x * mat.m[2][0] + a.y * mat.m[2][1] + a.z * mat.m[2][2]; | ||
165 | return *this; | ||
166 | } | ||
167 | |||
168 | Point& Point::TransMult(const Matrix3x3& mat, const Point& a) | ||
169 | { | ||
170 | x = a.x * mat.m[0][0] + a.y * mat.m[1][0] + a.z * mat.m[2][0]; | ||
171 | y = a.x * mat.m[0][1] + a.y * mat.m[1][1] + a.z * mat.m[2][1]; | ||
172 | z = a.x * mat.m[0][2] + a.y * mat.m[1][2] + a.z * mat.m[2][2]; | ||
173 | return *this; | ||
174 | } | ||
175 | |||
176 | Point& Point::Transform(const Point& r, const Matrix3x3& rotpos, const Point& linpos) | ||
177 | { | ||
178 | x = r.x * rotpos.m[0][0] + r.y * rotpos.m[0][1] + r.z * rotpos.m[0][2] + linpos.x; | ||
179 | y = r.x * rotpos.m[1][0] + r.y * rotpos.m[1][1] + r.z * rotpos.m[1][2] + linpos.y; | ||
180 | z = r.x * rotpos.m[2][0] + r.y * rotpos.m[2][1] + r.z * rotpos.m[2][2] + linpos.z; | ||
181 | return *this; | ||
182 | } | ||
183 | |||
184 | Point& Point::InvTransform(const Point& r, const Matrix3x3& rotpos, const Point& linpos) | ||
185 | { | ||
186 | float sx = r.x - linpos.x; | ||
187 | float sy = r.y - linpos.y; | ||
188 | float sz = r.z - linpos.z; | ||
189 | x = sx * rotpos.m[0][0] + sy * rotpos.m[1][0] + sz * rotpos.m[2][0]; | ||
190 | y = sx * rotpos.m[0][1] + sy * rotpos.m[1][1] + sz * rotpos.m[2][1]; | ||
191 | z = sx * rotpos.m[0][2] + sy * rotpos.m[1][2] + sz * rotpos.m[2][2]; | ||
192 | return *this; | ||
193 | } | ||