Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OOVoxel.m
Go to the documentation of this file.
1/*
2
3OOVoxel.m
4
5Oolite
6Copyright (C) 2004-2013 Giles C Williams and contributors
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21MA 02110-1301, USA.
22
23*/
24
25
26#import "OOMaths.h"
27
28
29// routines concerning octree voxels
30
31int checkFace(Vector p, GLfloat rd)
32{
33 int faces = 0;
34 if (p.x > rd) faces |= CUBE_FACE_RIGHT; // right
35 if (p.x < -rd) faces |= CUBE_FACE_LEFT; // left
36 if (p.y > rd) faces |= CUBE_FACE_TOP; // above
37 if (p.y < -rd) faces |= CUBE_FACE_BOTTOM; // below
38 if (p.z > rd) faces |= CUBE_FACE_FRONT; // ahead
39 if (p.z < -rd) faces |= CUBE_FACE_BACK; // behind
40 return faces ;
41}
42
43int checkBevel(Vector p, GLfloat rd)
44{
45 GLfloat r2 = rd * 2;
46 int bevels = 0;
47 if ( p.x + p.y > r2) bevels |= 0x001;
48 if ( p.x - p.y > r2) bevels |= 0x002;
49 if (-p.x + p.y > r2) bevels |= 0x004;
50 if (-p.x - p.y > r2) bevels |= 0x008;
51 if ( p.x + p.z > r2) bevels |= 0x010;
52 if ( p.x - p.z > r2) bevels |= 0x020;
53 if (-p.x + p.z > r2) bevels |= 0x040;
54 if (-p.x - p.z > r2) bevels |= 0x080;
55 if ( p.y + p.z > r2) bevels |= 0x100;
56 if ( p.y - p.z > r2) bevels |= 0x200;
57 if (-p.y + p.z > r2) bevels |= 0x400;
58 if (-p.y - p.z > r2) bevels |= 0x800;
59 return bevels;
60}
61
62int checkCorner(Vector p, GLfloat rd)
63{
64 GLfloat r3 = rd * 3;
65 int corners = 0;
66 if (( p.x + p.y + p.z) > r3) corners |= 0x01;
67 if (( p.x + p.y - p.z) > r3) corners |= 0x02;
68 if (( p.x - p.y + p.z) > r3) corners |= 0x04;
69 if (( p.x - p.y - p.z) > r3) corners |= 0x08;
70 if ((-p.x + p.y + p.z) > r3) corners |= 0x10;
71 if ((-p.x + p.y - p.z) > r3) corners |= 0x20;
72 if ((-p.x - p.y + p.z) > r3) corners |= 0x40;
73 if ((-p.x - p.y - p.z) > r3) corners |= 0x80;
74 return corners;
75}
76
77Vector lineIntersectionWithFace(Vector p1, Vector p2, long mask, GLfloat rd)
78{
79 if (CUBE_FACE_RIGHT & mask)
80 return make_vector( rd,
81 p1.y + (p2.y - p1.y) * (rd - p1.x) / (p2.x - p1.x),
82 p1.z + (p2.z - p1.z) * (rd - p1.x) / (p2.x - p1.x));
83
84 if (CUBE_FACE_LEFT & mask)
85 return make_vector( -rd,
86 p1.y + (p2.y - p1.y) * (-rd - p1.x) / (p2.x - p1.x),
87 p1.z + (p2.z - p1.z) * (-rd - p1.x) / (p2.x - p1.x));
88
89 if (CUBE_FACE_TOP & mask)
90 return make_vector( p1.x + (p2.x - p1.x) * (rd - p1.y) / (p2.y - p1.y),
91 rd,
92 p1.z + (p2.z - p1.z) * (rd - p1.y) / (p2.y - p1.y));
93
94 if (CUBE_FACE_BOTTOM & mask)
95 return make_vector( p1.x + (p2.x - p1.x) * (-rd - p1.y) / (p2.y - p1.y),
96 -rd,
97 p1.z + (p2.z - p1.z) * (-rd - p1.y) / (p2.y - p1.y));
98
99 if (CUBE_FACE_FRONT & mask)
100 return make_vector( p1.x + (p2.x - p1.x) * (rd - p1.z) / (p2.z - p1.z),
101 p1.y + (p2.y - p1.y) * (rd - p1.z) / (p2.z - p1.z),
102 rd);
103
104 if (CUBE_FACE_BACK & mask)
105 return make_vector( p1.x + (p2.x - p1.x) * (-rd - p1.z) / (p2.z - p1.z),
106 p1.y + (p2.y - p1.y) * (-rd - p1.z) / (p2.z - p1.z),
107 -rd);
108 return p1;
109}
110
111int checkPoint(Vector p1, Vector p2, GLfloat alpha, long mask, GLfloat rd)
112{
113 Vector pp;
114 pp.x = p1.x + alpha * (p2.x - p1.x);
115 pp.y = p1.y + alpha * (p2.y - p1.y);
116 pp.z = p1.z + alpha * (p2.z - p1.z);
117 return (checkFace( pp, rd) & mask);
118}
119
120int checkLine(Vector p1, Vector p2, int mask, GLfloat rd)
121{
122 int result = 0;
123 if ((CUBE_FACE_RIGHT & mask) && (p1.x > p2.x) && (checkPoint( p1, p2, (rd-p1.x)/(p2.x-p1.x), 0x3f - CUBE_FACE_RIGHT, rd) == 0)) // right
124 result |= CUBE_FACE_RIGHT;
125 if ((CUBE_FACE_LEFT & mask) && (p1.x < p2.x) && (checkPoint( p1, p2, (-rd-p1.x)/(p2.x-p1.x), 0x3f - CUBE_FACE_LEFT, rd) == 0)) // left
126 result |= CUBE_FACE_LEFT;
127 if ((CUBE_FACE_TOP & mask) && (p1.y > p2.y) && (checkPoint( p1, p2, (rd-p1.y)/(p2.y-p1.y), 0x3f - CUBE_FACE_TOP, rd) == 0)) // above
128 result |= CUBE_FACE_TOP;
129 if ((CUBE_FACE_BOTTOM & mask) && (p1.y < p2.y) && (checkPoint( p1, p2, (-rd-p1.y)/(p2.y-p1.y), 0x3f - CUBE_FACE_BOTTOM, rd) == 0)) // below
130 result |= CUBE_FACE_BOTTOM;
131 if ((CUBE_FACE_FRONT & mask) && (p1.z > p2.z) && (checkPoint( p1, p2, (rd-p1.z)/(p2.z-p1.z), 0x3f - CUBE_FACE_FRONT, rd) == 0)) // ahead
132 result |= CUBE_FACE_FRONT;
133 if ((CUBE_FACE_BACK & mask) && (p1.z < p2.z) && (checkPoint( p1, p2, (-rd-p1.z)/(p2.z-p1.z), 0x3f - CUBE_FACE_BACK, rd) == 0)) // behind
134 result |= CUBE_FACE_BACK;
135 return result;
136}
137
138// line v0 to v1 is compared with a cube centered on the origin (corners at -rd,-rd,-rd to rd,rd,rd).
139// returns -1 if the line intersects the cube.
140int lineCubeIntersection(Vector v0, Vector v1, GLfloat rd)
141{
142 int v0_test, v1_test;
143
144 // compare both vertexes with all six face-planes
145 //
146 if ((v0_test = checkFace( v0, rd)) == 0)
147 return -1; // v0 is inside the cube
148 if ((v1_test = checkFace( v1, rd)) == 0)
149 return -1; // v1 is inside the cube
150
151 // check they're not both outside one face-plane
152 //
153 if ((v0_test & v1_test) != 0)
154 return 0; // both v0 and v1 are outside the same face of the cube
155
156 // Now do the same test for the 12 edge planes
157 //
158 v0_test |= checkBevel( v0, rd) << 8;
159 v1_test |= checkBevel( v1, rd) << 8;
160 if ((v0_test & v1_test) != 0)
161 return 0; // v0 and v1 outside of the same bevel
162
163 // Now do the same test for the 8 corner planes
164 //
165 v0_test |= checkCorner( v0, rd) << 24;
166 v1_test |= checkCorner( v1, rd) << 24;
167 if ((v0_test & v1_test) != 0)
168 return 0; // v0 and v1 outside of same corner
169
170 // see if the v0-->v1 line intersects the cube.
171 //
172 return checkLine( v0, v1, v0_test | v1_test, rd);
173}
Vector lineIntersectionWithFace(Vector p1, Vector p2, long mask, GLfloat rd)
Definition OOVoxel.m:77
int checkCorner(Vector p, GLfloat rd)
Definition OOVoxel.m:62
int lineCubeIntersection(Vector v0, Vector v1, GLfloat rd)
Definition OOVoxel.m:140
int checkLine(Vector p1, Vector p2, int mask, GLfloat rd)
Definition OOVoxel.m:120
int checkPoint(Vector p1, Vector p2, GLfloat alpha, long mask, GLfloat rd)
Definition OOVoxel.m:111
int checkBevel(Vector p, GLfloat rd)
Definition OOVoxel.m:43
int checkFace(Vector p, GLfloat rd)
Definition OOVoxel.m:31