Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
SphereClass.h
1/* Renegade Scripts.dll
2 Copyright 2013 Tiberian Technologies
3
4 This file is part of the Renegade scripts.dll
5 The Renegade scripts.dll is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version. See the file COPYING for more details.
9 In addition, an exemption is given to allow Run Time Dynamic Linking of this code with any closed source module that does not contain code covered by this licence.
10 Only the source code to the module(s) containing the licenced code has to be released.
11*/
12#ifndef TT_INCLUDE__SPHERECLASS_H
13#define TT_INCLUDE__SPHERECLASS_H
14
15#include "Vector3.h"
16#include "Matrix3D.h"
17class SphereClass
18{
19public:
20 inline SphereClass(void) { };
21 inline SphereClass(const Vector3 & center,float radius) { Init(center,radius); }
22 inline SphereClass(const Vector3 & center,const SphereClass & s0);
23 inline SphereClass(const Vector3 *Position, const int VertCount);
24
25 inline void Init(const Vector3 & pos,float radius);
26 inline void Re_Center(const Vector3 & center);
27 inline void Add_Sphere(const SphereClass & s);
28 inline void Transform(const Matrix3D & tm);
29 inline float Volume(void) const;
30
31 inline SphereClass & operator += (const SphereClass & s);
32 inline SphereClass & operator *= (const Matrix3D & m);
33
34 Vector3 Center;
35 float Radius;
36};
37inline SphereClass::SphereClass(const Vector3 & center,const SphereClass & s0)
38{
39 float dist = (s0.Center - center).Length();
40 Center = center;
41 Radius = s0.Radius + dist;
42}
43inline SphereClass::SphereClass(const Vector3 *Position,const int VertCount)
44{
45 int i;
46 float dx,dy,dz;
47 Vector3 xmin(Position[0].X,Position[0].Y,Position[0].Z);
48 Vector3 xmax(Position[0].X,Position[0].Y,Position[0].Z);
49 Vector3 ymin(Position[0].X,Position[0].Y,Position[0].Z);
50 Vector3 ymax(Position[0].X,Position[0].Y,Position[0].Z);
51 Vector3 zmin(Position[0].X,Position[0].Y,Position[0].Z);
52 Vector3 zmax(Position[0].X,Position[0].Y,Position[0].Z);
53 for (i=1; i<VertCount; i++)
54 {
55 if (Position[i].X < xmin.X)
56 {
57 xmin.X = Position[i].X; xmin.Y = Position[i].Y; xmin.Z = Position[i].Z;
58 }
59 if (Position[i].X > xmax.X)
60 {
61 xmax.X = Position[i].X; xmax.Y = Position[i].Y; xmax.Z = Position[i].Z;
62 }
63 if (Position[i].Y < ymin.Y)
64 {
65 ymin.X = Position[i].X; ymin.Y = Position[i].Y; ymin.Z = Position[i].Z;
66 }
67 if (Position[i].Y > ymax.Y)
68 {
69 ymax.X = Position[i].X; ymax.Y = Position[i].Y; ymax.Z = Position[i].Z;
70 }
71 if (Position[i].Z < zmin.Z)
72 {
73 zmin.X = Position[i].X; zmin.Y = Position[i].Y; zmin.Z = Position[i].Z;
74 }
75 if (Position[i].Z > zmax.Z)
76 {
77 zmax.X = Position[i].X; zmax.Y = Position[i].Y; zmax.Z = Position[i].Z;
78 }
79 }
80 dx = xmax.X - xmin.X;
81 dy = xmax.Y - xmin.Y;
82 dz = xmax.Z - xmin.Z;
83 float xspan = dx*dx + dy*dy + dz*dz;
84 dx = ymax.X - ymin.X;
85 dy = ymax.Y - ymin.Y;
86 dz = ymax.Z - ymin.Z;
87 float yspan = dx*dx + dy*dy + dz*dz;
88 dx = zmax.X - zmin.X;
89 dy = zmax.Y - zmin.Y;
90 dz = zmax.Z - zmin.Z;
91 float zspan = dx*dx + dy*dy + dz*dz;
92 Vector3 dia1 = xmin;
93 Vector3 dia2 = xmax;
94 float maxspan = xspan;
95 if (yspan > maxspan)
96 {
97 maxspan = yspan;
98 dia1 = ymin;
99 dia2 = ymax;
100 }
101 if (zspan > maxspan)
102 {
103 maxspan = zspan;
104 dia1 = zmin;
105 dia2 = zmax;
106 }
107 Vector3 center;
108 center.X = (dia1.X + dia2.X) / 2.0f;
109 center.Y = (dia1.Y + dia2.Y) / 2.0f;
110 center.Z = (dia1.Z + dia2.Z) / 2.0f;
111 dx = dia2.X - center.X;
112 dy = dia2.Y - center.Y;
113 dz = dia2.Z - center.Z;
114 float radsqr = dx*dx + dy*dy + dz*dz;
115 float radius = sqrt(radsqr);
116 for (i=0; i<VertCount; i++)
117 {
118 dx = Position[i].X - center.X;
119 dy = Position[i].Y - center.Y;
120 dz = Position[i].Z - center.Z;
121 float testrad2 = dx*dx + dy*dy + dz*dz;
122 if (testrad2 > radsqr)
123 {
124 float testrad = sqrt(testrad2);
125 radius = (radius + testrad) / 2.0f;
126 radsqr = radius * radius;
127 float oldtonew = testrad - radius;
128 center.X = (radius * center.X + oldtonew * Position[i].X) / testrad;
129 center.Y = (radius * center.Y + oldtonew * Position[i].Y) / testrad;
130 center.Z = (radius * center.Z + oldtonew * Position[i].Z) / testrad;
131 }
132 }
133 Center = center;
134 Radius = radius;
135}
136inline void SphereClass::Init(const Vector3 & pos,float radius)
137{
138 Center = pos;
139 Radius = radius;
140}
141inline void SphereClass::Re_Center(const Vector3 & center)
142{
143 float dist = (Center - center).Length();
144 Center = center;
145 Radius += dist;
146}
147inline void SphereClass::Add_Sphere(const SphereClass & s)
148{
149 if (s.Radius == 0.0f)
150 {
151 return;
152 }
153 float dist = (s.Center - Center).Length();
154 if (dist == 0.0f)
155 {
156 Radius = (Radius > s.Radius) ? Radius : s.Radius;
157 return;
158 }
159 float rnew = (dist + Radius + s.Radius) / 2.0f;
160 if (rnew < Radius)
161 {
162 }
163 else
164 {
165 if (rnew < s.Radius)
166 {
167 Init(s.Center, s.Radius);
168 }
169 else
170 {
171 float lerp = (rnew - Radius) / dist;
172 Vector3 center = (s.Center - Center) * lerp + Center;
173 Init(center, rnew);
174 }
175 }
176}
177inline void SphereClass::Transform(const Matrix3D & tm)
178{
179 Center = tm * Center;
180}
181inline float SphereClass::Volume(void) const
182{
183 return (4.0f / 3.0f) * WWMATH_PI * (Radius * Radius * Radius);
184}
185inline SphereClass & SphereClass::operator += (const SphereClass & s)
186{
187 Add_Sphere(s);
188 return *this;
189}
190inline SphereClass & SphereClass::operator *= (const Matrix3D & m)
191{
192 Init(m * Center, Radius);
193 return *this;
194}
195inline bool Spheres_Intersect(const SphereClass & s0,const SphereClass & s1)
196{
197 Vector3 delta = s0.Center - s1.Center;
198 float dist2 = delta*delta;
199 if (dist2 < (s0.Radius + s1.Radius) * (s0.Radius + s1.Radius))
200 {
201 return true;
202 }
203 else
204 {
205 return false;
206 }
207}
208inline SphereClass Add_Spheres(const SphereClass & s0, const SphereClass & s1)
209{
210 if (s0.Radius == 0.0f)
211 {
212 return s1;
213 }
214 else
215 {
216 SphereClass result(s0);
217 result.Add_Sphere(s1);
218 return result;
219 }
220}
221inline SphereClass operator + (const SphereClass & s0,const SphereClass & s1)
222{
223 return Add_Spheres(s0,s1);
224}
225inline SphereClass Transform_Sphere(const Matrix3D & m, const SphereClass & s)
226{
227 return SphereClass(m*s.Center,s.Radius);
228}
229inline void Transform_Sphere(const Matrix3D & m, const SphereClass & s,SphereClass & res)
230{
231 res.Center = m*s.Center;
232 res.Radius = s.Radius;
233}
234inline SphereClass operator * (const Matrix3D & m, const SphereClass & s)
235{
236 return Transform_Sphere(m,s);
237}
238#endif