intravenous

annotate src/vein.cc @ 2:472c28b8b875

I think I pretty much nailed the camera
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 21 Apr 2012 23:03:36 +0300
parents
children 94d4c60af435
rev   line source
nuclear@1 1 #ifndef _MSC_VER
nuclear@1 2 #include <alloca.h>
nuclear@1 3 #else
nuclear@1 4 #include <malloc.h>
nuclear@1 5 #endif
nuclear@1 6 #include "vein.h"
nuclear@1 7 #include "geom.h"
nuclear@1 8
nuclear@1 9 Vein::Vein()
nuclear@1 10 {
nuclear@1 11 gen_dist = 8.0;
nuclear@1 12 subdiv = 8;
nuclear@1 13 ring_subdiv = 16;
nuclear@1 14 rad = 1.0;
nuclear@1 15
nuclear@1 16 idxbuf = 0;
nuclear@1 17 }
nuclear@1 18
nuclear@1 19 Vein::~Vein()
nuclear@1 20 {
nuclear@1 21 delete [] idxbuf;
nuclear@1 22 }
nuclear@1 23
nuclear@1 24 Vector3 Vein::calc_center(const Vector3 &ppos) const
nuclear@1 25 {
nuclear@1 26 // TODO add variation
nuclear@1 27 return Vector3(0.0, 0.0, ppos.z);
nuclear@1 28 }
nuclear@1 29
nuclear@1 30 Vector3 Vein::calc_dir(const Vector3 &ppos) const
nuclear@1 31 {
nuclear@1 32 // TODO add variation
nuclear@1 33 return Vector3(0, 0, 1);
nuclear@1 34 }
nuclear@1 35
nuclear@1 36 void Vein::build_idxbuf()
nuclear@1 37 {
nuclear@1 38 delete [] idxbuf;
nuclear@1 39
nuclear@1 40 int nfaces = subdiv * ring_subdiv;
nuclear@1 41 int nidx = nfaces * 4;
nuclear@1 42 idxbuf = new unsigned int[nidx];
nuclear@1 43 unsigned int *idxptr = idxbuf;
nuclear@1 44
nuclear@1 45 for(int i=0; i<subdiv; i++) {
nuclear@1 46 for(int j=0; j<ring_subdiv; j++) {
nuclear@1 47 idxptr[0] = i * ring_subdiv + j;
nuclear@1 48 idxptr[1] = i * ring_subdiv + ((j + 1) % ring_subdiv);
nuclear@1 49 idxptr[2] = idxptr[1] + ring_subdiv;
nuclear@1 50 idxptr[3] = idxptr[0] + ring_subdiv;
nuclear@1 51 idxptr += 4;
nuclear@1 52 }
nuclear@1 53 }
nuclear@1 54 }
nuclear@1 55
nuclear@1 56 void Vein::draw(const Vector3 &ppos) const
nuclear@1 57 {
nuclear@1 58 float start_z = ppos.z - gen_dist / 2.0;
nuclear@1 59 float dz = gen_dist / subdiv;
nuclear@1 60
nuclear@1 61 int nslices = subdiv + 1;
nuclear@1 62 int nverts = nslices * ring_subdiv;
nuclear@1 63 int nfaces = subdiv * ring_subdiv;
nuclear@1 64 Vertex *vbuf = (Vertex*)alloca(nverts * sizeof *vbuf);
nuclear@1 65 Vertex *vptr = vbuf;
nuclear@1 66
nuclear@1 67 Vector3 pt = ppos;
nuclear@1 68 pt.z = start_z;
nuclear@1 69
nuclear@1 70 for(int i=0; i<nslices; i++) {
nuclear@1 71 Vector3 cent = calc_center(pt);
nuclear@1 72 Vector3 dir = calc_dir(pt);
nuclear@1 73 Vector3 up(0, 1, 0);
nuclear@1 74 Vector3 right = cross_product(up, dir);
nuclear@1 75 up = cross_product(dir, right);
nuclear@1 76
nuclear@1 77 Matrix3x3 vrot{right, up, dir};
nuclear@1 78 //Quaternion vrot(dri, dtheta);
nuclear@1 79
nuclear@1 80 float theta = 0.0, dtheta = 2.0 * M_PI / ring_subdiv;
nuclear@1 81 for(int j=0; j<ring_subdiv; j++) {
nuclear@1 82 Vector3 vec = Vector3{-cos(theta) * rad, sin(theta) * rad, 0.0} + cent;
nuclear@1 83 vec.transform(vrot);
nuclear@1 84
nuclear@1 85 vptr->pos = vec;
nuclear@1 86 vptr->norm = cent - vec;
nuclear@1 87 vptr->tang = Vector3(); // TODO
nuclear@1 88 vptr->tc = Vector2(); // TODO
nuclear@1 89 vptr++;
nuclear@1 90
nuclear@1 91 theta += dtheta;
nuclear@1 92 }
nuclear@1 93
nuclear@1 94 pt.z += dz;
nuclear@1 95 }
nuclear@1 96
nuclear@1 97 // also create the index buffer if it's not valid
nuclear@1 98 if(!idxbuf) {
nuclear@1 99 ((Vein*)this)->build_idxbuf();
nuclear@1 100 }
nuclear@1 101
nuclear@1 102 // awesome, now draw it
nuclear@1 103 draw_mesh(GL_QUADS, nfaces * 4, vbuf, idxbuf);
nuclear@1 104 }