rayzor

annotate src/object.cc @ 14:a9a948809c6f

starting the renderer screen, plus misc stuff
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 13 Apr 2014 08:06:21 +0300
parents d94a69933a71
children 79609d482762
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 }