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 }
|