rev |
line source |
nuclear@14
|
1 #include <math.h>
|
nuclear@1
|
2 #include "object.h"
|
nuclear@1
|
3 #include "vmath.h"
|
nuclear@1
|
4 #include "min3d.h"
|
nuclear@9
|
5 #include "logger.h"
|
nuclear@1
|
6
|
nuclear@1
|
7 Object::Object()
|
nuclear@1
|
8 {
|
nuclear@12
|
9 type = NODE_OBJECT;
|
nuclear@1
|
10 }
|
nuclear@1
|
11
|
nuclear@1
|
12 Object::~Object()
|
nuclear@1
|
13 {
|
nuclear@1
|
14 }
|
nuclear@1
|
15
|
nuclear@1
|
16 // ---- sphere ----
|
nuclear@1
|
17 Sphere::Sphere()
|
nuclear@1
|
18 {
|
nuclear@1
|
19 }
|
nuclear@1
|
20
|
nuclear@1
|
21 Sphere::~Sphere()
|
nuclear@1
|
22 {
|
nuclear@1
|
23 }
|
nuclear@1
|
24
|
nuclear@9
|
25 #define USUB 12
|
nuclear@9
|
26 #define VSUB 6
|
nuclear@1
|
27
|
nuclear@14
|
28 void Sphere::draw(bool emph) const
|
nuclear@1
|
29 {
|
nuclear@1
|
30 static Vector3 *varr;
|
nuclear@9
|
31 static unsigned int *iarr;
|
nuclear@9
|
32 static int num_verts, num_indices;
|
nuclear@1
|
33 if(!varr) {
|
nuclear@9
|
34 int i, j;
|
nuclear@1
|
35 int uverts = USUB;
|
nuclear@1
|
36 int vverts = VSUB + 1;
|
nuclear@9
|
37
|
nuclear@1
|
38 num_verts = uverts * vverts;
|
nuclear@1
|
39 varr = new Vector3[num_verts];
|
nuclear@1
|
40
|
nuclear@1
|
41 Vector3 *vptr = varr;
|
nuclear@9
|
42 for(i=0; i<vverts; i++) {
|
nuclear@9
|
43 float v = (float)i / (float)VSUB;
|
nuclear@9
|
44 float phi = v * M_PI;
|
nuclear@9
|
45 for(j=0; j<uverts; j++) {
|
nuclear@9
|
46 float u = (float)j / (float)uverts;
|
nuclear@9
|
47 float theta = u * M_PI * 2.0;
|
nuclear@1
|
48
|
nuclear@9
|
49 float x = sin(theta) * sin(phi);
|
nuclear@12
|
50 float y = -cos(phi);
|
nuclear@9
|
51 float z = cos(theta) * sin(phi);
|
nuclear@1
|
52
|
nuclear@1
|
53 *vptr++ = Vector3(x, y, z);
|
nuclear@1
|
54 }
|
nuclear@1
|
55 }
|
nuclear@9
|
56
|
nuclear@9
|
57 num_indices = USUB * VSUB * 4;
|
nuclear@9
|
58 iarr = new unsigned int[num_indices];
|
nuclear@9
|
59
|
nuclear@9
|
60 unsigned int *iptr = iarr;
|
nuclear@9
|
61 for(i=0; i<VSUB; i++) {
|
nuclear@9
|
62 for(j=0; j<USUB; j++) {
|
nuclear@9
|
63 iptr[0] = i * uverts + j;
|
nuclear@9
|
64 iptr[1] = i * uverts + ((j + 1) % uverts);
|
nuclear@9
|
65 iptr[2] = iptr[1] + uverts;
|
nuclear@9
|
66 iptr[3] = iptr[0] + uverts;
|
nuclear@9
|
67 iptr += 4;
|
nuclear@9
|
68 }
|
nuclear@9
|
69 }
|
nuclear@9
|
70
|
nuclear@9
|
71 printlog("created sphere mesh\n");
|
nuclear@9
|
72 printlog(" vertices: %d (%d slices, %d stacks)\n", num_verts, uverts, vverts);
|
nuclear@9
|
73 printlog(" quads: %d (%d indices, %d usub, %d vsub)\n", USUB * VSUB, num_indices, USUB, VSUB);
|
nuclear@1
|
74 }
|
nuclear@1
|
75
|
nuclear@12
|
76 pre_draw();
|
nuclear@14
|
77 SceneNode::draw(emph);
|
nuclear@9
|
78
|
nuclear@5
|
79 m3d_vertex_array(&varr->x);
|
nuclear@9
|
80 m3d_draw_indexed(M3D_QUADS, iarr, num_indices);
|
nuclear@5
|
81 m3d_vertex_array(0);
|
nuclear@12
|
82
|
nuclear@12
|
83 post_draw();
|
nuclear@1
|
84 }
|
nuclear@12
|
85
|
nuclear@14
|
86 bool Sphere::intersect(const Ray &wray, float *dist) const
|
nuclear@12
|
87 {
|
nuclear@14
|
88 Ray ray = transform(get_inv_matrix(), wray);
|
nuclear@14
|
89
|
nuclear@14
|
90 // assumes center is 0,0,0, and radius is 1
|
nuclear@14
|
91 float a = dot(ray.dir, ray.dir);
|
nuclear@14
|
92 float b = 2.0 * ray.dir.x * ray.origin.x +
|
nuclear@14
|
93 2.0 * ray.dir.y * ray.origin.y +
|
nuclear@14
|
94 2.0 * ray.dir.z * ray.origin.z;
|
nuclear@14
|
95 float c = dot(ray.origin, ray.origin) - 1.0;
|
nuclear@14
|
96
|
nuclear@14
|
97 float discr = b * b - 4.0 * a * c;
|
nuclear@14
|
98 if(discr < 1e-4)
|
nuclear@14
|
99 return false;
|
nuclear@14
|
100
|
nuclear@14
|
101 float sqrt_discr = sqrt(discr);
|
nuclear@14
|
102 float t0 = (-b + sqrt_discr) / (2.0 * a);
|
nuclear@14
|
103 float t1 = (-b - sqrt_discr) / (2.0 * a);
|
nuclear@14
|
104
|
nuclear@14
|
105 if(t0 < 1e-4)
|
nuclear@14
|
106 t0 = t1;
|
nuclear@14
|
107 if(t1 < 1e-4)
|
nuclear@14
|
108 t1 = t0;
|
nuclear@14
|
109
|
nuclear@14
|
110 float t = t0 < t1 ? t0 : t1;
|
nuclear@14
|
111 if(t < 1e-4)
|
nuclear@14
|
112 return false;
|
nuclear@14
|
113
|
nuclear@14
|
114 if(dist) *dist = t;
|
nuclear@14
|
115 return true;
|
nuclear@12
|
116 }
|
nuclear@12
|
117
|
nuclear@12
|
118 // ---- box ----
|
nuclear@12
|
119
|
nuclear@12
|
120 Box::Box()
|
nuclear@12
|
121 {
|
nuclear@12
|
122 }
|
nuclear@12
|
123
|
nuclear@12
|
124 Box::~Box()
|
nuclear@12
|
125 {
|
nuclear@12
|
126 }
|
nuclear@12
|
127
|
nuclear@12
|
128 /*
|
nuclear@12
|
129 3--------2
|
nuclear@12
|
130 /. .\
|
nuclear@12
|
131 0------------1
|
nuclear@12
|
132 | 7--------6 |
|
nuclear@12
|
133 |/ \|
|
nuclear@12
|
134 4------------5
|
nuclear@12
|
135
|
nuclear@12
|
136 */
|
nuclear@14
|
137 void Box::draw(bool emph) const
|
nuclear@12
|
138 {
|
nuclear@12
|
139 static const float verts[] = {
|
nuclear@12
|
140 -1, 1, 1,
|
nuclear@12
|
141 1, 1, 1,
|
nuclear@12
|
142 1, 1, -1,
|
nuclear@12
|
143 -1, 1, -1,
|
nuclear@12
|
144 -1, -1, 1,
|
nuclear@12
|
145 1, -1, 1,
|
nuclear@12
|
146 1, -1, -1,
|
nuclear@12
|
147 -1, -1, -1
|
nuclear@12
|
148 };
|
nuclear@12
|
149 static const unsigned int indices[] = {
|
nuclear@12
|
150 0, 1, 2, 3, // top
|
nuclear@12
|
151 4, 7, 6, 5, // bottom
|
nuclear@12
|
152 0, 4, 5, 1, // front
|
nuclear@12
|
153 5, 6, 2, 1, // right
|
nuclear@12
|
154 6, 7, 3, 2, // back
|
nuclear@12
|
155 7, 4, 0, 3 // left
|
nuclear@12
|
156 };
|
nuclear@12
|
157
|
nuclear@12
|
158 pre_draw();
|
nuclear@14
|
159 SceneNode::draw(emph);
|
nuclear@12
|
160
|
nuclear@12
|
161 m3d_vertex_array(verts);
|
nuclear@12
|
162 m3d_draw_indexed(M3D_QUADS, indices, sizeof indices / sizeof *indices);
|
nuclear@12
|
163 m3d_vertex_array(0);
|
nuclear@12
|
164
|
nuclear@12
|
165 post_draw();
|
nuclear@12
|
166 }
|
nuclear@12
|
167
|
nuclear@12
|
168 bool Box::intersect(const Ray &ray, float *dist) const
|
nuclear@12
|
169 {
|
nuclear@12
|
170 return false; // TODO
|
nuclear@12
|
171 }
|