1 /***********************************************************************
2 * d:/Werk/src/csmash-0.3.8.new/conv/parts.h
3 * $Id: parts.h,v 1.16 2003/07/28 17:03:10 nan Exp $
4 *
5 * Copyright by ESESoft.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer
16 * in the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * The name of the author may not be used to endorse or promote
20 * products derived from this software without specific prior written
21 * permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
24 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
27 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 ***********************************************************************/
36 #ifndef __wata_ESESoft_9465__parts_h__INCLUDED__
37 #define __wata_ESESoft_9465__parts_h__INCLUDED__
38 /***********************************************************************/
39 #include <algorithm>
40 #include <vector>
41
42 #include "float"
43 #include "matrix"
44 #include "affine"
45
46 /* __BEGIN__BEGIN__ */
47
48 vector4F Affine2Quaternion(affine4F aff);
49 affine4F Quaternion2Affine(vector4F v, vector4F p);
50
51 class edge {
52 public:
53 short v0, v1;
54 short p0, p1;
55 };
56
57 class color4b
58 {
59 public:
60 typedef unsigned char element_t;
61 typedef unsigned char byte;
62 enum {
63 element_size = 4,
64 };
65 byte r, g, b, a;
color4b()66 inline color4b() {}
r(i)67 inline color4b(byte i, byte a=255) : r(i), g(i), b(i), a(a) {}
68 inline color4b(byte r, byte g, byte b, byte a=255) :
r(r)69 r(r), g(g), b(b), a(a) {}
70
element_array()71 byte* element_array() { return (byte*)this; }
element_array()72 const byte* element_array() const { return (byte*)this; }
73
glBind()74 void glBind() const { glColor4ubv((const GLubyte*)element_array()); }
75 };
76
77 class color4f
78 {
79 public:
80 typedef unsigned char element_t;
81 enum {
82 element_size = 4,
83 };
84
85 float r, g, b, a;
86
color4f()87 inline color4f() {}
88 inline color4f(int i, int a=255) : r(i/255.0F), g(i/255.0F), b(i/255.0F), a(a/255.0F) {}
89 inline color4f(int r, int g, int b, int a=255) :
90 r(r/255.0F), g(g/255.0F), b(b/255.0F), a(a/255.0F) {}
91
element_array()92 float* element_array() { return (float*)this; }
element_array()93 const float* element_array() const { return (float*)this; }
94
glBind()95 void glBind() const { glColor4fv(element_array()); }
96 };
97
98 class colormap
99 {
100 public:
101 typedef color4f color_t;
102 enum {
103 map_size = 256,
104 };
105
106 bool load(const char *file);
fill(const color_t & c)107 void fill(const color_t& c) {
108 std::fill(&map[0], &map[map_size], c);
109 }
110 inline color_t& operator [](int i) { return map[i]; }
111 inline const color_t& operator [](int i) const { return map[i]; }
112
113 public:
114 color_t map[map_size];
115 };
116
117 class polygon;
118
119 class polyhedron
120 {
121 public:
122 int numPoints, numPolygons, numEdges;
123 vector3F *points;
124 vector3F *texcoord;
125 short (*polygons)[4];
126 unsigned char *cindex;
127 vector3F (*normals)[4];
128 vector3F *planeNormal;
129 edge *edges;
130 char *filename;
131 GLuint texturename;
132 colormap cmap;
133
134 polyhedron(const char *filename);
135 ~polyhedron();
136 polyhedron& operator *=(const affine4F &m); //normal vectors are destroyed
137
polsize(int i)138 inline int polsize(int i) const { return (0 > polygons[i][3]) ? 3 : 4; }
139 polygon getPolygon(int i) const;
140
141 void getNormal();
142
143 protected:
144 void initColormap();
145 };
146
147 /// polygon access object
148 class polygon
149 {
150 friend class polyhedron;
151 protected:
polygon(const polyhedron & parent,int polynum)152 inline polygon(const polyhedron& parent, int polynum)
153 : p(parent), num(polynum) {
154 size = (p.polygons[num][3] < 0) ? 3 : 4;
155 }
156
157 public:
round(int idx)158 inline int round(int idx) const { return (idx+size)%size; }
pround(int idx)159 inline int pround(int idx) const { return idx%size; }
160
ri(int idx)161 inline short ri(int idx) const { return p.polygons[num][idx]; }
i(int idx)162 inline short i(int idx) const { return p.polygons[num][round(idx)]; }
163
rv(int idx)164 inline const vector3F& rv(int idx) const { return p.points[ri(idx)]; }
v(int idx)165 inline const vector3F& v(int idx) const { return p.points[i(idx)]; }
166
rst(int idx)167 inline const vector3F& rst(int idx) const { return p.texcoord[ri(idx)]; }
st(int idx)168 inline const vector3F& st(int idx) const { return p.texcoord[i(idx)]; }
169
rn(int idx)170 inline const vector3F& rn(int idx) const { return p.normals[num][idx]; }
n(int idx)171 inline const vector3F& n(int idx) const { return p.normals[num][round(idx)]; }
n(void)172 inline const vector3F& n(void) const { return p.planeNormal[num]; }
173
c()174 inline const unsigned char c() const { return p.cindex[num]; }
175
getv(short vidx)176 inline short getv(short vidx) const {
177 for (int k = 0; size > k; ++k) if (vidx == ri(k)) return k;
178 return -1;
179 }
gete(const edge & e,int * way)180 inline short gete(const edge&e, int* way) const {
181 return gete(e.v0, e.v1, way);
182 }
gete(short v0,short v1,int * way)183 inline short gete(short v0, short v1, int* way) const {
184 for (int k = 0; size > k; ++k) {
185 if (v0 == ri(k)) {
186 if (v1 == ri(pround(k+1))) {
187 *way = +1;
188 return k;
189 }
190 else if (v1 == i(k-1)) {
191 *way = -1;
192 return k;
193 }
194 }
195 }
196 return -1;
197 }
198
glBeginSize()199 inline GLenum glBeginSize() const {
200 return (3 == size) ? GL_TRIANGLES : GL_QUADS;
201 }
202
203 public:
204 const polyhedron& p;
205 int num;
206 int size;
207 };
208
getPolygon(int i)209 inline polygon polyhedron::getPolygon(int i) const {
210 return polygon(*this, i);
211 }
212
213 class affineanim {
214 public:
215 int numFrames;
216 affine4F *matrices;
217
218 affineanim(int num);
219 affineanim(const char *filename);
220 ~affineanim();
221
222 inline const affine4F& operator[](int i) const {
223 return matrices[i];
224 }
225 inline affine4F& operator [](int i) {
226 return matrices[i];
227 }
228 };
229
230 class affinemotion {
231 public:
232 polyhedron ref;
233 affineanim anim;
234
235 affinemotion(const char *ref, const char *anim);
236 void write(const char *basename);
valid()237 inline bool valid() const {
238 return ref.numPoints > 0 && anim.numFrames > 0;
239 }
240 };
241
242 class quaternionanim {
243 public:
244 int numFrames;
245 std::vector<vector4F> quaternions;
246 vector3F origin;
247
248 quaternionanim(int num);
249 quaternionanim(const char *filename);
250 ~quaternionanim();
251
252 inline const vector4F& operator[](int i) const {
253 return quaternions[i];
254 }
255 inline const vector4F operator[](float i) const {
256 if ( i == (int)i ) {
257 return quaternions[(int)i];
258 } else {
259 vector4F q1 = quaternions[(int)i];
260 vector4F q2 = quaternions[(int)i+1];
261 if ( q1[1]*q2[1]+q1[2]*q2[2]+q1[3]*q2[3] < 0 )
262 q2 = -q2;
263 return q1*(1-(i-(int)i)) + q2*(i-(int)i);
264 }
265 }
266 inline vector4F& operator [](int i) {
267 return quaternions[i];
268 }
269 inline vector4F operator[](float i) {
270 if ( i == (int)i ) {
271 return quaternions[(int)i];
272 } else {
273 vector4F q1 = quaternions[(int)i];
274 vector4F q2 = quaternions[(int)i+1];
275 if ( q1[1]*q2[1]+q1[2]*q2[2]+q1[3]*q2[3] < 0 )
276 q2 = -q2;
277 return q1*(1-(i-(int)i)) + q2*(i-(int)i);
278 }
279 }
280 };
281
282 class quaternionmotion {
283 public:
284 polyhedron ref;
285 quaternionanim anim;
286
287 quaternionmotion(const char *ref, const char *anim);
288 //void write(const char *basename);
valid()289 inline bool valid() const {
290 return ref.numPoints > 0 && anim.numFrames > 0;
291 }
292 };
293
294 class partsmotion
295 {
296 public:
297 int numParts;
298
299 static polyhedron **polyparts;
300 affineanim *origin;
301 quaternionanim **qanim;
302
303 partsmotion(const char *basename);
304 virtual ~partsmotion();
305
306 virtual bool render(int frame, float xdiff, float ydiff, float zdiff);
307 virtual bool render(double frame, float xdiff, float ydiff, float zdiff);
308 virtual bool renderWire(int frame, float xdiff, float ydiff, float zdiff);
309 virtual bool renderWire(double frame, float xdiff, float ydiff, float zdiff);
310 virtual bool renderArmOnly(double frame, float xdiff, float ydiff, float zdiff);
311
312 private:
313 void drawleg( float xdiff, float ydiff, float zdiff, bool isWireFrame );
314 void legIK( vector3F hip, vector3F &knee, vector3F &heel, vector3F toe,
315 float thighLength, float shinLength, float footSize,
316 bool isWireFrame );
317 void drawbody( vector3F neck, vector3F waist, bool isWireFrame );
318
319 void renderparts( int partsNum, bool isWireFrame );
320 };
321
322 /* __END__END__ */
323
324 /***********************************************************************/
325 #endif
326 /***********************************************************************
327 * END OF parts.h
328 ***********************************************************************/
329