Explorar el Código

Added Camera, Emitter, Mesh, Particle, ViewVolume

Thomas Buck hace 10 años
padre
commit
e7b6c7bf7b
Se han modificado 11 ficheros con 2414 adiciones y 0 borrados
  1. 194
    0
      include/Camera.h
  2. 179
    0
      include/Emitter.h
  3. 169
    0
      include/Mesh.h
  4. 119
    0
      include/Particle.h
  5. 200
    0
      include/ViewVolume.h
  6. 5
    0
      src/CMakeLists.txt
  7. 246
    0
      src/Camera.cpp
  8. 245
    0
      src/Emitter.cpp
  9. 625
    0
      src/Mesh.cpp
  10. 162
    0
      src/Particle.cpp
  11. 270
    0
      src/ViewVolume.cpp

+ 194
- 0
include/Camera.h Ver fichero

@@ -0,0 +1,194 @@
1
+/*!
2
+ * \file include/Camera.h
3
+ * \brief OpenGL camera class
4
+ *
5
+ * \author Mongoose
6
+ */
7
+#ifndef _CAMERA_H_
8
+#define _CAMERA_H_
9
+
10
+#include "math/math.h"
11
+#include "math/Matrix.h"
12
+#include "math/Quaternion.h"
13
+
14
+/*!
15
+ * \brief Commands for interactive camera control
16
+ */
17
+enum camera_command {
18
+  CAMERA_MOVE_FORWARD = 1,
19
+  CAMERA_MOVE_BACKWARD,
20
+  CAMERA_MOVE_UP,
21
+  CAMERA_MOVE_DOWN,
22
+  CAMERA_ROTATE_RIGHT,
23
+  CAMERA_ROTATE_LEFT,
24
+  CAMERA_SPEED_UP,
25
+  CAMERA_SPEED_DOWN,
26
+  CAMERA_ROTATE_UP,
27
+  CAMERA_ROTATE_DOWN,
28
+  CAMERA_MOVE_LEFT,
29
+  CAMERA_MOVE_RIGHT
30
+};
31
+
32
+/*!
33
+ * \brief Flags a camera can have
34
+ */
35
+enum CameraFlags {
36
+    Camera_FlyMode = (1 << 0) //!< Camera is flying free?
37
+};
38
+
39
+/*!
40
+ * \brief OpenGL camera class
41
+ *
42
+ * 2002.12.16:
43
+ * Mongoose - Removed perspective setting and OpenGL dependency
44
+ *            API changes to reflect new direction of this object:
45
+ *              Removing outdated algorithms and code
46
+ *              And refactoring the class in general
47
+ *
48
+ * 2001.06.06:
49
+ * Mongoose - Moving GLU code into here to setup break up
50
+ *            into Camera base class, DynamicCamera,
51
+ *            and GLUCamera child classes
52
+ *
53
+ * 2001.06.04:
54
+ * Mongoose - Quaternion based compile option
55
+ *
56
+ * 2001.05.18:
57
+ * Mongoose - Created, based on my old GL camera code
58
+ *            that has been used in GooseEgg since alpha
59
+ *            and algorithms from Yuri Zhivago's trview
60
+ */
61
+class Camera {
62
+public:
63
+    /*!
64
+     * \brief Constructs an object of Camera
65
+     */
66
+    Camera();
67
+
68
+    /*!
69
+     * \brief Returns the current position
70
+     * \param pos where the position will be stored
71
+     */
72
+    void getPosition(vec3_t pos);
73
+
74
+    /*!
75
+     * \brief Returns the up vector
76
+     * \param up where the up vector will be stored
77
+     */
78
+    void getUp(vec3_t up);
79
+
80
+    /*!
81
+     * \brief Get the target currently looked at
82
+     * \param target where the target will be stored
83
+     */
84
+    void getTarget(vec3_t target);
85
+
86
+    /*!
87
+     * \brief Get current yaw in degrees
88
+     * \returns yaw in degrees
89
+     */
90
+    float getYaw();
91
+
92
+    /*!
93
+     * \brief Get angle/yaw of camera
94
+     * \returns theta angle/yaw of camera
95
+     */
96
+    vec_t getRadianYaw();
97
+
98
+    /*!
99
+     * \brief Get current angle/pitch
100
+     * \returns current pitch in degrees
101
+     */
102
+    float getPitch();
103
+
104
+    /*!
105
+     * \brief Get angle/pitch of camera
106
+     * \returns phi angle/pitch of camera
107
+     */
108
+    vec_t getRadianPitch();
109
+
110
+    /*!
111
+     * \brief Rotate the camera
112
+     * \param angle angle in radians
113
+     * \param x X coordinate of axis
114
+     * \param y Y coordinate of axis
115
+     * \param z Z coordinate of axis
116
+     */
117
+    void rotate(float angle, float x, float y, float z);
118
+
119
+    /*!
120
+     * \brief Set Camera position
121
+     * \param x new X coordinate
122
+     * \param y new Y coordinate
123
+     * \param z new Z coordinate
124
+     */
125
+    void translate(float x, float y, float z);
126
+
127
+    /*!
128
+     * \brief Set the Camera to its initial state
129
+     */
130
+    void reset();
131
+
132
+    /*!
133
+     * \brief Sets the X rotation delta
134
+     * \param angle thetas rotation delta in degrees
135
+     */
136
+    void setSensitivityX(float angle);
137
+
138
+    /*!
139
+     * \brief Sets the Y rotation delta
140
+     * \param angle thetas rotation delta in degrees
141
+     */
142
+    void setSensitivityY(float angle);
143
+
144
+    /*!
145
+     * \brief Sends interactive command to camera
146
+     * \param cmd valid camera command
147
+     */
148
+    void command(enum camera_command cmd);
149
+
150
+    /*!
151
+     * \brief Sets speed
152
+     * \param s new speed, is 256 or greater in general
153
+     */
154
+    void setSpeed(float s);
155
+
156
+    /*!
157
+     * \brief Updates view target
158
+     */
159
+    void update();
160
+
161
+    /*!
162
+     * \brief Set current position
163
+     * \param pos new position
164
+     */
165
+    void setPosition(vec3_t pos);
166
+
167
+    /*!
168
+     * \brief Sets the up vector
169
+     * \param up new up vector
170
+     */
171
+    void setUp(vec3_t up);
172
+
173
+    /*!
174
+     * \brief Sets target (look at pos)
175
+     * \param target new target
176
+     */
177
+    void setTarget(vec3_t target);
178
+
179
+private:
180
+    Quaternion mQ;                //!< Quaternion for rotation
181
+    unsigned int mFlags;          //!< For testing with flags
182
+    vec_t mPos[4];                //!< Location in 3 space (aka eye)
183
+    vec_t mTarget[4];             //!< Postition we're looking at
184
+    vec_t mUp[4];                 //!< Up vector
185
+    vec_t mSide[4];               //!< Side vector
186
+    vec_t mViewDistance;          //!< Distance from target
187
+    vec_t mTranslateDelta;        //!< Step size to move
188
+    vec_t mRotateDelta;           //!< Radians to rotate Y
189
+    vec_t mTheta;                 //!< View angle Y
190
+    vec_t mRotateDelta2;          //!< Radians to rotate Z
191
+    vec_t mTheta2;                //!< View angle Z
192
+};
193
+
194
+#endif

+ 179
- 0
include/Emitter.h Ver fichero

@@ -0,0 +1,179 @@
1
+/*!
2
+ * \file include/Emitter.h
3
+ * \brief Particle emitter class.
4
+ *
5
+ * \author Mongoose
6
+ */
7
+
8
+#ifndef _EMITTER_H_
9
+#define _EMITTER_H_
10
+
11
+#include "Particle.h"
12
+
13
+/*!
14
+ * \brief Particle emitter class.
15
+ */
16
+class Emitter {
17
+public:
18
+
19
+    /*!
20
+     * \brief Flags an Emitter can have
21
+     */
22
+    typedef enum {
23
+        fUseFrustumCulling = (1 << 0), //!< Use frustum culling
24
+        fUseDepthSorting   = (1 << 1)  //!< Use depth sorting
25
+    } EmitterFlags;
26
+
27
+
28
+    /*!
29
+     * \brief Constructs an object of Emitter
30
+     * \param name valid C string
31
+     * \param n greater than 0
32
+     */
33
+    Emitter(const char *name, int n);
34
+
35
+    /*!
36
+     * \brief Deconstructs an object of Emitter
37
+     */
38
+    ~Emitter();
39
+
40
+    /*!
41
+     * \brief Get the particles
42
+     * \returns array of Particles
43
+     */
44
+    Particle *Particles();
45
+
46
+    /*!
47
+     * \brief Number of particles emitted
48
+     * \returns Number of particles emitted
49
+     */
50
+    int Count();
51
+
52
+    /*!
53
+     * \brief Sets position of emitter in 3D space
54
+     * \param x X coordinate
55
+     * \param y Y coordinate
56
+     * \param z Z coordinate
57
+     */
58
+    void Pos(float x, float y, float z);
59
+
60
+    /*!
61
+     * \brief Returns position of emitter in 3D space
62
+     * \param x Where X coordinate will be stored
63
+     * \param y Where Y coordinate will be stored
64
+     * \param z Where Z coordinate will be stored
65
+     */
66
+    void Pos(float *x, float *y, float *z);
67
+
68
+    /*!
69
+     * \brief Sets orientation of emitter in 3D space
70
+     * \param x X coordinate
71
+     * \param y Y coordinate
72
+     * \param z Z coordinate
73
+     */
74
+    void Orientation(float x, float y, float z);
75
+
76
+    /*!
77
+     * \brief Returns orientation of emitter in 3D space
78
+     * \param x Where X coordinate will be stored
79
+     * \param y Where Y coordinate will be stored
80
+     * \param z Where Z coordinate will be stored
81
+     */
82
+    void Orientation(float *x, float *y, float *z);
83
+
84
+    /*!
85
+     * \brief Get the flags of this Emitter
86
+     * \returns EmitterFlags
87
+     */
88
+    unsigned int Flags();
89
+
90
+    /*!
91
+     * \brief Set or Unset a flag
92
+     * \param flag EmitterFlag to change
93
+     * \param op new state (true - set)
94
+     */
95
+    void Flags(unsigned int flag, bool op);
96
+
97
+    /*!
98
+     * \brief Allocates the particle array and sets the count.
99
+     * If the array has been allocated previously it will be
100
+     * deallocated and a new one made.
101
+     * \param n new size, greater than 0
102
+     */
103
+    void ParticleArray(int n);
104
+
105
+    /*!
106
+     * \brief Renders the particles
107
+     */
108
+    void Draw();
109
+
110
+    /*!
111
+     * \brief Sets the emitters name
112
+     * \param name is a valid C string
113
+     */
114
+    void Name(const char *name);
115
+
116
+    /*!
117
+     * \brief Resets all particle texture ids
118
+     * \param id new id
119
+     * \sa Particle::TextureId()
120
+     */
121
+    void SetTextureId(int id);
122
+
123
+    /*!
124
+     * \brief Set the texture id for a range of particles in the array
125
+     * \param particle_start start of range
126
+     * \param particle_end end of range
127
+     * \param id new id
128
+     * \sa Particle::TextureId()
129
+     */
130
+    void TextureId(unsigned int particle_start, unsigned int particle_end, int id);
131
+
132
+    /*!
133
+     * \brief Set the color of a range of particles in the array
134
+     * \param particle_start start of range
135
+     * \param particle_end end of range
136
+     * \param r new red part of color (0.0 to 1.0)
137
+     * \param g new green part of color (0.0 to 1.0)
138
+     * \param b new blue part of color (0.0 to 1.0)
139
+     * \sa Particle::Color()
140
+     */
141
+    void Color(unsigned int particle_start, unsigned int particle_end, float r, float g, float b);
142
+
143
+    /*!
144
+     * \brief Set the speed of a range of particles in the array.
145
+     * Take note that the speed starts out at 2000, and lower means faster.
146
+     * \param particle_start start of range
147
+     * \param particle_end end of range
148
+     * \param x X speed
149
+     * \param y Y speed
150
+     * \param z Z speed
151
+     * \sa Particle::Speed
152
+     */
153
+    void Speed(unsigned int particle_start, unsigned int particle_end, float x, float y, float z);
154
+
155
+    /*!
156
+     * \brief Let a force (eg. Gravity) act on a range of particles in the array
157
+     * \param particle_start start of range
158
+     * \param particle_end end of range
159
+     * \param x X force
160
+     * \param y Y force
161
+     * \param z Z force
162
+     * \sa Particle::Force()
163
+     */
164
+    void Force(unsigned int particle_start, unsigned int particle_end, float x, float y, float z);
165
+
166
+    static vec_t mFrustum[6][4]; //!< View Volume copy
167
+
168
+private:
169
+    static int compareParticleDist(const void *voidA, const void *voidB);
170
+
171
+    char *_name;         //!< Emitter name
172
+    unsigned int _flags; //!< Emitter flags
173
+    vec3_t _pos;         //!< Position in 3D space
174
+    vec3_t _mangle;      //!< Oreintation in 3D space
175
+    Particle *_particle; //!< Array of particles
176
+    unsigned int _count; //!< Particle count
177
+};
178
+
179
+#endif

+ 169
- 0
include/Mesh.h Ver fichero

@@ -0,0 +1,169 @@
1
+/*!
2
+ * \file include/Mesh.h
3
+ * \brief OpenGL Mesh
4
+ *
5
+ * \author Mongoose
6
+ *
7
+ * \todo Unify the parallel systems here, arrays and the allocate/set
8
+ */
9
+
10
+#ifndef _MESH_H_
11
+#define _MESH_H_
12
+
13
+#include "math/math.h"
14
+
15
+/*!
16
+ * \brief OpenGL Mesh
17
+ */
18
+class Mesh {
19
+public:
20
+
21
+    typedef enum {
22
+        MeshModeSolid,
23
+        MeshModeWireframe,
24
+        MeshModeTexture,
25
+        MeshModeMultiTexture
26
+    } MeshMode;
27
+
28
+    typedef enum {
29
+        fMesh_UseVertexArray = (1 << 0)
30
+    } MeshFlags;
31
+
32
+    typedef struct {
33
+        int texture;
34
+#ifdef MULTITEXTURE
35
+        int bumpmap;
36
+#endif
37
+
38
+        unsigned int cnum_triangles;
39
+        unsigned int cnum_alpha_triangles;
40
+
41
+        unsigned int num_texcoors;
42
+        vec2_t *texcoors;
43
+
44
+        unsigned int num_texcoors2;
45
+        vec2_t *texcoors2;
46
+
47
+        //! Arrays of triangle indices sorted by texture
48
+        unsigned int num_triangles;
49
+        unsigned int *triangles; //!< ABCABCABC...
50
+
51
+        //! Arrays of alpha triangle indices sorted by texture
52
+        unsigned int num_alpha_triangles;
53
+        unsigned int *alpha_triangles; //!< ABCABCABC...
54
+    } tris_t;
55
+
56
+    typedef struct {
57
+
58
+        int texture;
59
+#ifdef MULTITEXTURE
60
+        int bumpmap;
61
+#endif
62
+
63
+        unsigned int cnum_quads;
64
+        unsigned int cnum_alpha_quads;
65
+
66
+        unsigned int num_texcoors;
67
+        vec2_t *texcoors;
68
+
69
+        unsigned int num_texcoors2;
70
+        vec2_t *texcoors2;
71
+
72
+        //! Arrays of rectangle indices sorted by texture
73
+        unsigned int num_quads;
74
+        unsigned int *quads; //!< ABCDABCDABCD...
75
+
76
+        //! Arrays of alpha rectangle indices sorted by texture
77
+        unsigned int num_alpha_quads;
78
+        unsigned int *alpha_quads; //!< ABCDABCDABCD...
79
+
80
+    } rect_t;
81
+
82
+    /*!
83
+     * \brief Constructs an object of Mesh
84
+     */
85
+    Mesh();
86
+
87
+    /*!
88
+     * \brief Deconstructs an object of Mesh
89
+     */
90
+    ~Mesh();
91
+
92
+    void drawAlpha();
93
+
94
+    void drawSolid();
95
+
96
+    void allocateColors(unsigned int n);
97
+
98
+    void allocateNormals(unsigned int n);
99
+
100
+    void allocateRectangles(unsigned int n);
101
+
102
+    void allocateTriangles(unsigned int n);
103
+
104
+    void allocateVertices(unsigned int n);
105
+
106
+    void bufferColorArray(unsigned int colorCount, vec_t *colors);
107
+
108
+    void bufferNormalArray(unsigned int normalCount, vec_t *normals);
109
+
110
+    void bufferTriangles(unsigned int count,
111
+                            unsigned int *indices, vec_t *texCoords,
112
+                            int *textures, unsigned int *flags);
113
+
114
+    void bufferVertexArray(unsigned int vertexCount, vec_t *vertices);
115
+
116
+    void setColor(unsigned int index, float r, float g, float b, float a);
117
+
118
+    void setColor(unsigned int index, float rgba[4]);
119
+
120
+    void setNormal(unsigned int index, float i, float j, float k);
121
+
122
+    void setVertex(unsigned int index, float x, float y, float z);
123
+
124
+#ifdef NOT_IMPLEMENTED
125
+    void sortFacesByTexture();
126
+
127
+    void addFace(int textureIndex, int textureIndexB, unsigned int flags,
128
+                    unsigned int vertexIndexCount, vec_t *vertexIndices);
129
+
130
+    void addTexTiledFace(int textureIndex, int textureIndexB,
131
+                            unsigned int flags, unsigned int indexCount,
132
+                            vec_t *vertexIndices, vec_t *texcoords);
133
+
134
+    void bufferTexcoords(unsigned int texcoordCount, vec_t *texcoords);
135
+
136
+    void duplicateArraysForTexTiledTexcoords();
137
+#endif
138
+
139
+    unsigned int mFlags;
140
+
141
+    MeshMode mMode;
142
+
143
+    unsigned int mNumVertices;
144
+    vec3_t *mVertices; //!< XYZ
145
+
146
+    unsigned int mNumNormals;
147
+    vec3_t *mNormals; //!< IJK
148
+
149
+    unsigned int mNumColors;
150
+    vec4_t *mColors; //!< RGBA
151
+
152
+    unsigned int mNumTris;
153
+    tris_t *mTris;
154
+
155
+    unsigned int mNumQuads;
156
+    rect_t *mQuads;
157
+
158
+    unsigned int mTriangleCount;
159
+    int *mTriangleTextures;
160
+    unsigned int *mTriangleIndices;
161
+    unsigned int *mTriangleFlags;
162
+    vec_t *mTriangleTexCoordArray;
163
+
164
+    vec_t *mVertexArray;
165
+    vec_t *mNormalArray;
166
+    vec_t *mColorArray;
167
+};
168
+
169
+#endif

+ 119
- 0
include/Particle.h Ver fichero

@@ -0,0 +1,119 @@
1
+/*!
2
+ * \file include/Particle.h
3
+ * \brief Particle system base header
4
+ *
5
+ * \author Mongoose
6
+ */
7
+
8
+#ifndef _PARTICLE_H_
9
+#define _PARTICLE_H_
10
+
11
+#include "math/math.h"
12
+
13
+/*!
14
+ * \brief Partcle systems atomic base
15
+ */
16
+class Particle {
17
+public:
18
+
19
+    /*!
20
+     * \brief Constructs an object of Sound
21
+     */
22
+    Particle();
23
+
24
+    /*!
25
+     * \brief Toggles active state of particle
26
+     * \param active new state
27
+     */
28
+    void setActive(bool active);
29
+
30
+    /*!
31
+     * \brief Sets gravity/force acting on particle
32
+     * \param x X part of force vector
33
+     * \param y Y part
34
+     * \param z Z part
35
+     */
36
+    void Force(float x, float y, float z);
37
+
38
+    /*!
39
+     * \brief Resets particle to defaults
40
+     */
41
+    void Reset();
42
+
43
+    /*!
44
+     * \brief Sets gravity/force acting on particle
45
+     * \note speed inits at 2000, lower is faster
46
+     * \param x X part of speed vector
47
+     * \param y Y part
48
+     * \param z Z part
49
+     */
50
+    void Speed(float x, float y, float z);
51
+
52
+    /*!
53
+     * \brief Sets new particle coloring
54
+     * \note White {1.0, 1.0, 1.0} is the init color
55
+     * \param r Red part, from 0.0 to 1.0
56
+     * \param g Green part, from 0.0 to 1.0
57
+     * \param b Blue part, from 0.0 to 1.0
58
+     */
59
+    void Color(float r, float g, float b);
60
+
61
+    /*!
62
+     * \brief Returns position of particle in 3 space
63
+     * \param x not NULL!
64
+     * \param y not NULL!
65
+     * \param z not NULL!
66
+     */
67
+    void Pos(float *x, float *y, float *z);
68
+
69
+    /*!
70
+     * \brief Returns current color of particle
71
+     * \param r not NULL!
72
+     * \param g not NULL!
73
+     * \param b not NULL!
74
+     */
75
+    void Color(float *r, float *g, float *b);
76
+
77
+    /*!
78
+     * \brief Returns current life (blend) of particle
79
+     * \returns fade of particle
80
+     */
81
+    float Life();
82
+
83
+    /*!
84
+     * \brief Adjusts for particle life cycle
85
+     */
86
+    void Update();
87
+
88
+    /*!
89
+     * \brief Returns texture binding for this particle
90
+     * \returns texture id
91
+     */
92
+    int Texture();
93
+
94
+    /*!
95
+     * \brief Returns active value
96
+     * \returns state
97
+     */
98
+    bool isActive();
99
+
100
+    /*!
101
+     * \brief Set the texture for this particle
102
+     * \param t new texture id
103
+     */
104
+    void TextureId(int t);
105
+
106
+
107
+private:
108
+    bool _active;  //!< Is this particle in use?
109
+    float _life;   //!< Life of particle
110
+    float _blend;  //!< Blend amount or fade
111
+    int _texture;  //!< Texture polygon to use
112
+    vec3_t _pos;   //!< Current position in 3 space
113
+    vec3_t _color; //!< Current color
114
+    vec3_t _dir;   //!< Current direction
115
+    vec3_t _force; //!< Current force or 'gravity'
116
+    vec3_t _speed; //!< Speed of particle movement
117
+};
118
+
119
+#endif

+ 200
- 0
include/ViewVolume.h Ver fichero

@@ -0,0 +1,200 @@
1
+/*!
2
+ * \file include/ViewVolume.h
3
+ * \brief Viewing Volume for culling use
4
+ *
5
+ * \author Mongoose
6
+ */
7
+
8
+#ifndef _VIEWVOLUME_H_
9
+#define _VIEWVOLUME_H_
10
+
11
+#include "math/Matrix.h"
12
+
13
+/*!
14
+ * \brief Defines a 3D sphere.
15
+ */
16
+class BoundingSphere {
17
+public:
18
+    vec3_t mCenter; //!< Center of bounding sphere
19
+    vec_t mRadius; //!< Raduis of bounding sphere
20
+};
21
+
22
+/*!
23
+ * \brief Defines a 3D rectangle.
24
+ */
25
+class BoundingBox {
26
+public:
27
+    vec3_t mMin; //!< Bounding box MIN point
28
+    vec3_t mMax; //!< Bounding box MAX point
29
+};
30
+
31
+/*!
32
+ * \brief Defines a 3D sphere and/or rectangle.
33
+ */
34
+class BoundingVolume {
35
+public:
36
+    BoundingSphere mSphere; //!< Bounding sphere of this volume
37
+    BoundingBox mBox; //!< Bounding box of this volume
38
+};
39
+
40
+/*!
41
+ * \brief Viewing Volume for culling use
42
+ */
43
+class ViewVolume {
44
+public:
45
+
46
+    /*!
47
+     * \brief Sides of the view volume
48
+     */
49
+    enum ViewVolumeSide {
50
+        rightSide  = 0, //!< Right
51
+        leftSide   = 1, //!< Left
52
+        bottomSide = 2, //!< Bottom
53
+        topSide    = 3, //!< Top
54
+        farSide    = 4, //!< Back
55
+        nearSide   = 5  //!< Front
56
+    };
57
+
58
+    /*!
59
+     * \brief Planes of the view volume
60
+     */
61
+    enum ViewVolumePlane {
62
+        planeA = 0, //!< X value of normal
63
+        planeB = 1, //!< Y value of normal
64
+        planeC = 2, //!< Z value of normal
65
+        planeD = 3  //!< Distance to origin
66
+    };
67
+
68
+    /*!
69
+     * \brief Constructs an object of ViewVolume
70
+     */
71
+    ViewVolume();
72
+
73
+    /*!
74
+     * \brief Check if bounding volume is in view volume
75
+     * \param bvol bounding volume to check
76
+     * \returns true if frustum contains the given bounding volume
77
+     */
78
+    bool isBoundingVolumeInFrustum(BoundingVolume bvol);
79
+
80
+    /*!
81
+     * \brief Check if bounding sphere is in view volume
82
+     * \param bvol bounding sphere to check
83
+     * \returns true if frustum contains the given bounding volume
84
+     */
85
+    bool isBoundingSphereInFrustum(BoundingSphere bvol);
86
+
87
+    /*!
88
+     * \brief Check if bounding box is in view volume
89
+     * \param bvol bounding box to check
90
+     * \returns true if frustum contains the given bounding volume
91
+     */
92
+    bool isBoundingBoxInFrustum(BoundingBox bvol);
93
+
94
+    /*!
95
+     * \brief Check if point is in view volume
96
+     * \param x X coordinate of point
97
+     * \param y Y coordinate of point
98
+     * \param z Z coordinate of point
99
+     * \returns true if point in view volume
100
+     */
101
+    bool isPointInFrustum(vec_t x, vec_t y, vec_t z);
102
+
103
+    /*!
104
+     * \brief Check if bounding sphere is in view volume
105
+     * \param x X coordinate of a valid abstract sphere
106
+     * \param y Y coordinate of a valid abstract sphere
107
+     * \param z Z coordinate of a valid abstract sphere
108
+     * \param radius radius of a valid abstract sphere
109
+     * \returns true if abstract sphere in view volume
110
+     */
111
+    bool isSphereInFrustum(vec_t x, vec_t y, vec_t z, vec_t radius);
112
+
113
+    /*!
114
+     * \brief Check if bounding box is in view volume
115
+     * \param min minimum point of valid abstract bounding box
116
+     * \param max maximum point of valid abstract bounding box
117
+     * \returns true if abstract bounding box in view volume
118
+     */
119
+    bool isBboxInFrustum(vec3_t min, vec3_t max);
120
+
121
+    /*!
122
+     * \brief Distance to Bounding sphere
123
+     * \param x X coordinate of a valid abstract sphere
124
+     * \param y Y coordinate of a valid abstract sphere
125
+     * \param z Z coordinate of a valid abstract sphere
126
+     * \param radius radius of a valid abstract sphere
127
+     * \returns distance to abstract sphere bounding volume
128
+     */
129
+    vec_t getDistToSphereFromNear(vec_t x, vec_t y, vec_t z, vec_t radius);
130
+
131
+    /*!
132
+     * \brief Distance to Bounding box
133
+     * \param min minimum point of a valid abstract bounding box
134
+     * \param max maximum point of a valid abstract bounding box
135
+     * \returns distance to abstract box bounding volume
136
+     */
137
+    vec_t getDistToBboxFromNear(vec3_t min, vec3_t max);
138
+
139
+    /*!
140
+     * \brief Get a copy of the view volume
141
+     * \param frustum where frustum will be stored
142
+     */
143
+    void getFrustum(vec_t frustum[6][4]);
144
+
145
+    /*!
146
+     * \brief Get a copy of a given plane in view volume
147
+     * \param p side
148
+     * \param plane wher plane will be stored
149
+     */
150
+    void getPlane(ViewVolumeSide p, vec4_t plane);
151
+
152
+    /*!
153
+     * \brief Updates view volume for this frame.
154
+     * \param proj new projection matrix
155
+     * \param mdl new model matrix
156
+     */
157
+    void updateFrame(matrix_t proj, matrix_t mdl);
158
+
159
+    /*!
160
+     * \brief Updates view volume for this frame.
161
+     *
162
+     * Model & Projection Matrices must be set.
163
+     */
164
+    void updateFrame();
165
+
166
+    /*!
167
+     * \brief Set this class' model matrix
168
+     * \param mdl new model matrix
169
+     */
170
+    void setModel(matrix_t mdl);
171
+
172
+    /*!
173
+     * \brief Set this class' projection matrix
174
+     * \param proj new projection matrix
175
+     */
176
+    void setProjection(matrix_t proj);
177
+
178
+private:
179
+
180
+    /*!
181
+     * \brief Computes clipping matrix.
182
+     *
183
+     * Model & Projection matrices must be set!
184
+     */
185
+    void updateClip();
186
+
187
+    /*!
188
+     * \brief Computes planes of frustum.
189
+     *
190
+     * Model, Projection & Clip matrices must be set!
191
+     */
192
+    void updateFrustum();
193
+
194
+    Matrix mProjection;   //!< Projection matrix
195
+    Matrix mModel;        //!< Model matrix
196
+    Matrix mClip;         //!< Clipping matrix
197
+    vec_t mFrustum[6][4]; //!< View volume
198
+};
199
+
200
+#endif

+ 5
- 0
src/CMakeLists.txt Ver fichero

@@ -31,13 +31,18 @@ set (LIBS ${LIBS} ${ZLIB_LIBRARIES})
31 31
 #################################################################
32 32
 
33 33
 # Set Source files
34
+set (SRCS ${SRCS} "Camera.cpp")
34 35
 set (SRCS ${SRCS} "Console.cpp")
36
+set (SRCS ${SRCS} "Emitter.cpp")
35 37
 set (SRCS ${SRCS} "Game.cpp")
36 38
 set (SRCS ${SRCS} "main.cpp")
37 39
 set (SRCS ${SRCS} "Menu.cpp")
40
+set (SRCS ${SRCS} "Mesh.cpp")
38 41
 set (SRCS ${SRCS} "OpenRaider.cpp")
42
+set (SRCS ${SRCS} "Particle.cpp")
39 43
 set (SRCS ${SRCS} "Sound.cpp")
40 44
 set (SRCS ${SRCS} "TombRaider.cpp")
45
+set (SRCS ${SRCS} "ViewVolume.cpp")
41 46
 set (SRCS ${SRCS} "Window.cpp")
42 47
 
43 48
 # Select available Windowing library

+ 246
- 0
src/Camera.cpp Ver fichero

@@ -0,0 +1,246 @@
1
+/*!
2
+ * \file src/Camera.cpp
3
+ * \brief OpenGL camera class
4
+ *
5
+ * \author Mongoose
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <math.h>
10
+
11
+#include "Camera.h"
12
+
13
+Camera::Camera() {
14
+    mFlags = 0;
15
+    mViewDistance = 14.0f;
16
+    mTranslateDelta = 256.0f;
17
+    mRotateDelta = OR_DEG_TO_RAD(15.0f);
18
+    mRotateDelta2 = OR_DEG_TO_RAD(5.0f);
19
+    mFlags &= Camera_FlyMode;
20
+    reset();
21
+}
22
+
23
+void Camera::getPosition(vec3_t pos) {
24
+    pos[0] = mPos[0];
25
+    pos[1] = mPos[1];
26
+    pos[2] = mPos[2];
27
+}
28
+
29
+void Camera::getUp(vec3_t up) {
30
+    up[0] = mUp[0];
31
+    up[1] = mUp[1];
32
+    up[2] = mUp[2];
33
+}
34
+
35
+void Camera::getTarget(vec3_t target) {
36
+    target[0] = mTarget[0];
37
+    target[1] = mTarget[1];
38
+    target[2] = mTarget[2];
39
+}
40
+
41
+float Camera::getYaw() {
42
+    return OR_RAD_TO_DEG(mTheta);
43
+}
44
+
45
+vec_t Camera::getRadianYaw() {
46
+    return mTheta;
47
+}
48
+
49
+vec_t Camera::getRadianPitch() {
50
+    return mTheta2;
51
+}
52
+
53
+void Camera::rotate(float angle, float x, float y, float z) {
54
+    Quaternion t, n;
55
+    Matrix matrix;
56
+    vec_t side[4] = { 1.0f, 0.0f,  0.0f, 1.0f };
57
+    vec_t up[4] =   { 0.0f, 1.0f,  0.0f, 1.0f };
58
+    vec_t look[4] = { 0.0f, 0.0f, -1.0f, 1.0f };
59
+    unsigned int i;
60
+    matrix_t m;
61
+
62
+    t.set(angle, x, y, z);
63
+    n = mQ * t;
64
+    n.normalize();
65
+
66
+    n.getMatrix(m);
67
+    matrix.setMatrix(m);
68
+    matrix.multiply4v(side, mSide);
69
+    matrix.multiply4v(look, mTarget);
70
+    matrix.multiply4v(up, mUp);
71
+
72
+    for (i = 0; i < 3; ++i) {
73
+        mSide[i] += mPos[i];
74
+        mTarget[i] += mPos[i];
75
+        mUp[i] += mPos[i];
76
+    }
77
+
78
+    mQ = n;
79
+}
80
+
81
+void Camera::translate(float x, float y, float z) {
82
+    int i;
83
+    vec_t result[4];
84
+    vec_t v[4];
85
+    matrix_t m;
86
+    Matrix matrix;
87
+
88
+    v[0] = x;
89
+    v[1] = y;
90
+    v[2] = -z;
91
+    v[3] = 1;
92
+
93
+    m[0] = mSide[0] - mPos[0];
94
+    m[1] = mUp[0] - mPos[0];
95
+    m[2] = mTarget[0] - mPos[0];
96
+    m[3] = 0;
97
+    m[4] = mSide[1] - mPos[1];
98
+    m[5] = mUp[1] - mPos[1];
99
+    m[6] = mTarget[1] - mPos[1];
100
+    m[7] = 0;
101
+    m[8] = mSide[2] - mPos[2];
102
+    m[9] = mUp[2] - mPos[2];
103
+    m[10] = mTarget[2] - mPos[2];
104
+    m[11] = 0;
105
+    m[12] = 0;
106
+    m[13] = 0;
107
+    m[14] = 0;
108
+    m[15] = 1;
109
+
110
+    matrix.setMatrix(m);
111
+    matrix.multiply4v(v, result);
112
+
113
+    for (i = 0; i < 3; ++i) {
114
+        mSide[i] += result[i];
115
+        mUp[i] += result[i];
116
+        mTarget[i] += result[i];
117
+        mPos[i] += result[i];
118
+    }
119
+
120
+    mPos[0] = x;
121
+    mPos[1] = y;
122
+    mPos[2] = z;
123
+}
124
+
125
+void Camera::reset() {
126
+    mTheta = 0.0f;
127
+    mTheta2 = 0.0f;
128
+
129
+    mPos[0] = 0.0f;
130
+    mPos[1] = 0.0f;
131
+    mPos[2] = 0.0f;
132
+
133
+    mTarget[0] = 0.0f;
134
+    mTarget[1] = 0.0f;
135
+    mTarget[2] = mViewDistance;
136
+
137
+    mSide[0] = 1.0f;
138
+    mSide[1] = 0.0f;
139
+    mSide[2] = 0.0f;
140
+
141
+    mUp[0] = 0.0f;
142
+    mUp[1] = 1.0f;
143
+    mUp[2] = 0.0f;
144
+
145
+    mQ.setIdentity();
146
+    translate(0.0f, 0.0f, 0.0f);
147
+}
148
+
149
+void Camera::setSensitivityY(float angle) {
150
+    mRotateDelta2 = OR_DEG_TO_RAD(angle);
151
+}
152
+
153
+void Camera::setSensitivityX(float angle) {
154
+    mRotateDelta = OR_DEG_TO_RAD(angle);
155
+}
156
+
157
+void Camera::command(enum camera_command cmd) {
158
+    switch (cmd) {
159
+        case CAMERA_MOVE_FORWARD:
160
+            if (mFlags & Camera_FlyMode)
161
+                mPos[2] += (mTranslateDelta * cosf(mTheta));
162
+
163
+            mPos[0] += (mTranslateDelta * sinf(mTheta));
164
+            mPos[1] += (mTranslateDelta * sinf(mTheta2));
165
+            break;
166
+        case CAMERA_MOVE_BACKWARD:
167
+            if (mFlags & Camera_FlyMode)
168
+                mPos[2] -= (mTranslateDelta * cosf(mTheta));
169
+
170
+            mPos[0] -= (mTranslateDelta * sinf(mTheta));
171
+            mPos[1] -= (mTranslateDelta * sinf(mTheta2));
172
+            break;
173
+        case CAMERA_MOVE_LEFT:
174
+            mPos[0] -= (mTranslateDelta * sinf(mTheta - 90.0f));
175
+            mPos[2] -= (mTranslateDelta * cosf(mTheta - 90.0f));
176
+            break;
177
+        case CAMERA_MOVE_RIGHT:
178
+            mPos[0] -= (mTranslateDelta * sinf(mTheta + 90.0f));
179
+            mPos[2] -= (mTranslateDelta * cosf(mTheta + 90.0f));
180
+            break;
181
+        case CAMERA_ROTATE_UP:
182
+            if (mTheta2 < (M_PI / 2)) {
183
+                mTheta2 += mRotateDelta2;
184
+                rotate(mTheta2, 1.0f, 0.0f, 0.0f);
185
+            }
186
+            break;
187
+        case CAMERA_ROTATE_DOWN:
188
+            if (mTheta2 > -(M_PI / 2)) {
189
+                mTheta2 -= mRotateDelta2;
190
+                rotate(mTheta2, 1.0f, 0.0f, 0.0f);
191
+            }
192
+            break;
193
+        case CAMERA_ROTATE_RIGHT:
194
+            mTheta += mRotateDelta;
195
+            rotate(mTheta, 0.0f, 1.0f, 0.0f);
196
+            break;
197
+        case CAMERA_ROTATE_LEFT:
198
+            mTheta -= mRotateDelta;
199
+            rotate(mTheta, 0.0f, 1.0f, 0.0f);
200
+            break;
201
+        case CAMERA_MOVE_UP:
202
+            mPos[1] -= mTranslateDelta / 2.0f;
203
+            mTarget[1] -= mTranslateDelta / 2.0f;
204
+            break;
205
+        case CAMERA_MOVE_DOWN:
206
+            mPos[1] += mTranslateDelta / 2.0f;
207
+            mTarget[1] += mTranslateDelta / 2.0f;
208
+            break;
209
+        case CAMERA_SPEED_UP:
210
+            ++mTranslateDelta;
211
+            break;
212
+        case CAMERA_SPEED_DOWN:
213
+            if (--mTranslateDelta < 0.0f)
214
+                mTranslateDelta = 1.0f;
215
+            break;
216
+    }
217
+}
218
+
219
+void Camera::setSpeed(float s) {
220
+    mTranslateDelta = s;
221
+}
222
+
223
+void Camera::update() {
224
+    mTarget[2] = (mViewDistance * cosf(mTheta)) + mPos[2];
225
+    mTarget[0] = (mViewDistance * sinf(mTheta)) + mPos[0];
226
+    mTarget[1] = (mViewDistance * sinf(mTheta2)) + mPos[1]; // + height_offset;
227
+}
228
+
229
+void Camera::setPosition(vec3_t pos) {
230
+    mPos[0] = pos[0];
231
+    mPos[1] = pos[1];
232
+    mPos[2] = pos[2];
233
+}
234
+
235
+void Camera::setUp(vec3_t up) {
236
+    mUp[0] = up[0];
237
+    mUp[1] = up[1];
238
+    mUp[2] = up[2];
239
+}
240
+
241
+void Camera::setTarget(vec3_t target) {
242
+    mTarget[0] = target[0];
243
+    mTarget[1] = target[1];
244
+    mTarget[2] = target[2];
245
+}
246
+

+ 245
- 0
src/Emitter.cpp Ver fichero

@@ -0,0 +1,245 @@
1
+/*!
2
+ * \file src/Emitter.cpp
3
+ * \brief Particle emitter class.
4
+ *
5
+ * \author Mongoose
6
+ */
7
+
8
+#include <stdlib.h>
9
+#include <string.h>
10
+#include <stdio.h>
11
+
12
+#ifdef __APPLE__
13
+#include <OpenGL/gl.h>
14
+#include <OpenGL/glu.h>
15
+#else
16
+#include <GL/gl.h>
17
+#include <GL/glu.h>
18
+#endif
19
+
20
+#include "Emitter.h"
21
+
22
+vec_t Emitter::mFrustum[6][4];
23
+
24
+int Emitter::compareParticleDist(const void *voidA, const void *voidB) {
25
+    Particle *a = const_cast<Particle *>(static_cast<const Particle *>(voidA));
26
+    Particle *b = const_cast<Particle *>(static_cast<const Particle *>(voidB));
27
+    float x, y, z, distA, distB;
28
+
29
+    if (!a || !b)
30
+        return -1; // error really
31
+
32
+    a->Pos(&x, &y, &z);
33
+    distA = (Emitter::mFrustum[5][0] * x +
34
+            Emitter::mFrustum[5][1] * y +
35
+            Emitter::mFrustum[5][2] * z +
36
+            Emitter::mFrustum[5][3]);
37
+
38
+    b->Pos(&x, &y, &z);
39
+    distB = (Emitter::mFrustum[5][0] * x +
40
+            Emitter::mFrustum[5][1] * y +
41
+            Emitter::mFrustum[5][2] * z +
42
+            Emitter::mFrustum[5][3]);
43
+
44
+    // reverse less/greater than
45
+    // less than
46
+    if (distA > distB)
47
+        return -1;
48
+
49
+    // greater than ( no need for equal )
50
+    return 1;
51
+}
52
+
53
+Emitter::Emitter(const char *name, int n) {
54
+    _name = NULL;
55
+    _flags = 0;
56
+    _particle = NULL;
57
+    _count = 0;
58
+    _pos[0] = _pos[1] = _pos[2] = 0.0;
59
+    _mangle[0] = _mangle[1] = _mangle[2] = 0.0;
60
+
61
+    Name(name);
62
+    ParticleArray(n);
63
+}
64
+
65
+Emitter::~Emitter() {
66
+    if (_name)
67
+        delete [] _name;
68
+
69
+    if (_particle)
70
+        delete [] _particle;
71
+
72
+    _count = 0;
73
+}
74
+
75
+Particle *Emitter::Particles() {
76
+    return _particle;
77
+}
78
+
79
+
80
+int Emitter::Count() {
81
+    return _count;
82
+}
83
+
84
+void Emitter::Pos(float *x, float *y, float *z) {
85
+    *x = _pos[0];
86
+    *y = _pos[1];
87
+    *z = _pos[2];
88
+}
89
+
90
+void Emitter::Pos(float x, float y, float z) {
91
+    _pos[0] = x;
92
+    _pos[1] = y;
93
+    _pos[2] = z;
94
+}
95
+
96
+void Emitter::Orientation(float *x, float *y, float *z) {
97
+    *x = _mangle[0];
98
+    *y = _mangle[1];
99
+    *z = _mangle[2];
100
+}
101
+
102
+void Emitter::Orientation(float x, float y, float z) {
103
+    _mangle[0] = x;
104
+    _mangle[1] = y;
105
+    _mangle[2] = z;
106
+}
107
+
108
+unsigned int Emitter::Flags() {
109
+    return _flags;
110
+}
111
+
112
+void Emitter::Flags(unsigned int flag, bool op) {
113
+    _flags |= flag;
114
+
115
+    if (!op)
116
+        _flags ^= flag;
117
+}
118
+
119
+void Emitter::ParticleArray(int n) {
120
+    if (n) {
121
+        if (_particle) {
122
+            _count = 0;
123
+            delete [] _particle;
124
+        }
125
+
126
+        _count = n;
127
+        _particle = new Particle[_count];
128
+    }
129
+}
130
+
131
+void Emitter::Name(const char *name) {
132
+    if (name && name[0]) {
133
+        if (_name)
134
+            delete [] _name;
135
+
136
+        int l = strlen(name);
137
+        _name = new char[l+1];
138
+
139
+        // Mongoose 2002.01.09, Mongoose says 'Only you can prevent overflows'
140
+        strncpy(_name, name, l);
141
+        _name[l] = 0;
142
+    }
143
+}
144
+
145
+void Emitter::SetTextureId(int id) {
146
+    for (unsigned int i = 0; i < _count; i++)
147
+        _particle[i].TextureId(id);
148
+}
149
+
150
+void Emitter::TextureId(unsigned int particle_start, unsigned int particle_end, int id) {
151
+    if ((particle_start < _count) && (particle_end > 0 && particle_end <= _count) && (particle_start < particle_end)) {
152
+        for (unsigned int i = particle_start; i < particle_end; i++)
153
+            _particle[i].TextureId(id);
154
+    }
155
+}
156
+
157
+void Emitter::Color(unsigned int particle_start, unsigned int particle_end, float r, float g, float b) {
158
+    if ((particle_start < _count) && (particle_end > 0 && particle_end <= _count) && (particle_start < particle_end)) {
159
+        for (unsigned int i = particle_start; i < particle_end; i++)
160
+            _particle[i].Color(r, g, b);
161
+    }
162
+}
163
+
164
+void Emitter::Speed(unsigned int particle_start, unsigned int particle_end, float x, float y, float z) {
165
+    if ((particle_start < _count) && (particle_end > 0 && particle_end <= _count) && (particle_start < particle_end)) {
166
+        for (unsigned int i = particle_start; i < particle_end; i++)
167
+            _particle[i].Speed(x, y, z);
168
+    }
169
+}
170
+
171
+void Emitter::Force(unsigned int particle_start, unsigned int particle_end, float x, float y, float z) {
172
+    if ((particle_start < _count) && (particle_end > 0 && particle_end <= _count) && (particle_start < particle_end)) {
173
+        for (unsigned int i = particle_start; i < particle_end; i++)
174
+            _particle[i].Force(x, y, z);
175
+    }
176
+}
177
+
178
+void Emitter::Draw() {
179
+    unsigned int i, p;
180
+    float x, y, z;
181
+    float r, g, b;
182
+    float life;
183
+
184
+    if (!_count || !_particle) {
185
+        printf("Emitter::Draw> No particles!\n");
186
+        return;
187
+    }
188
+
189
+    glPushMatrix();
190
+
191
+    //glRotatef(_mangle[0], 1.0, 0.0, 0.0);
192
+    //glRotatef(_mangle[1], 0.0, 1.0, 0.0);
193
+    //glRotatef(_mangle[2], 0.0, 0.0, 1.0);
194
+    //glTranslatef(_pos[0], _pos[1], _pos[2]);
195
+
196
+    if (_flags & fUseDepthSorting)
197
+        qsort(_particle, _count, sizeof(Particle), compareParticleDist);
198
+
199
+    for (i = 0; i < _count; i++) {
200
+        if (_particle[i].isActive()) {
201
+            _particle[i].Pos(&x, &y, &z);
202
+
203
+            if (_flags & fUseFrustumCulling) {
204
+                for (p = 0; p < 6; ++p) {
205
+                    if (((mFrustum[p][0] * x) + (mFrustum[p][1] * y) + (mFrustum[p][2] * z) + mFrustum[p][3]) < 0) {
206
+                        _particle[i].setActive(false);
207
+                        break;
208
+                    }
209
+                }
210
+
211
+                if (!_particle[i].isActive())
212
+                    continue;
213
+            }
214
+
215
+            _particle[i].Color(&r, &g, &b);
216
+            life = _particle[i].Life();
217
+
218
+            // Mongoose 2002.01.01, Removed Texture agent dep
219
+            glBindTexture(GL_TEXTURE_2D, _particle[i].Texture());
220
+
221
+            // Alpha is determined by life, which is affected by blend amount
222
+            glColor4f(r, g, b, life);
223
+
224
+            // Render tristrip quad
225
+            glBegin(GL_TRIANGLE_STRIP);
226
+            glTexCoord2d(1.0, 1.0);
227
+            glVertex3f(x + 0.5f, y + 0.5f, z);
228
+
229
+            glTexCoord2d(0.0, 1.0);
230
+            glVertex3f(x - 0.5f, y + 0.5f, z);
231
+
232
+            glTexCoord2d(1.0, 0.0);
233
+            glVertex3f(x + 0.5f, y - 0.5f, z);
234
+
235
+            glTexCoord2d(0.0, 0.0);
236
+            glVertex3f(x - 0.5f, y - 0.5f, z);
237
+            glEnd();
238
+
239
+            // Update particle's attributes for it's life cycle
240
+            _particle[i].Update();
241
+        }
242
+    }
243
+
244
+    glPopMatrix();
245
+}

+ 625
- 0
src/Mesh.cpp Ver fichero

@@ -0,0 +1,625 @@
1
+/*!
2
+ * \file src/Mesh.cpp
3
+ * \brief OpenGL Mesh
4
+ *
5
+ * \author Mongoose
6
+ */
7
+
8
+#include <stdlib.h>
9
+#include <assert.h>
10
+
11
+#ifdef __APPLE__
12
+#include <OpenGL/gl.h>
13
+#else
14
+#include <GL/gl.h>
15
+#endif
16
+
17
+#include "Mesh.h"
18
+
19
+
20
+////////////////////////////////////////////////////////////
21
+// Constructors
22
+////////////////////////////////////////////////////////////
23
+
24
+Mesh::Mesh()
25
+{
26
+    mNumVertices = 0;
27
+    mVertices = 0x0;
28
+
29
+    mNumNormals = 0;
30
+    mNormals = 0x0;
31
+
32
+    mNumColors = 0;
33
+    mColors = 0x0;
34
+
35
+    mNumTris = 0;
36
+    mTris = 0x0;
37
+
38
+    mNumQuads = 0;
39
+    mQuads = 0x0;
40
+
41
+    mVertexArray = 0x0;
42
+    mNormalArray = 0x0;
43
+    mColorArray = 0x0;
44
+
45
+    mTriangleCount = 0;
46
+    mTriangleTextures = 0x0;
47
+    mTriangleIndices = 0x0;
48
+    mTriangleFlags = 0x0;
49
+    mTriangleTexCoordArray = 0x0;
50
+
51
+    mFlags = 0;
52
+    mMode = MeshModeTexture;
53
+}
54
+
55
+
56
+Mesh::~Mesh()
57
+{
58
+    unsigned int i;
59
+
60
+
61
+    if (mVertices)
62
+    {
63
+        delete [] mVertices;
64
+    }
65
+
66
+    if (mNormals)
67
+    {
68
+        delete [] mNormals;
69
+    }
70
+
71
+    if (mColors)
72
+    {
73
+        delete [] mColors;
74
+    }
75
+
76
+    if (mTris)
77
+    {
78
+        for (i = 0; i < mNumTris; ++i)
79
+        {
80
+            if (mTris[i].triangles)
81
+                delete [] mTris[i].triangles;
82
+
83
+            if (mTris[i].alpha_triangles)
84
+                delete [] mTris[i].alpha_triangles;
85
+
86
+            if (mTris[i].texcoors)
87
+                delete [] mTris[i].texcoors;
88
+
89
+            if (mTris[i].texcoors2)
90
+                delete [] mTris[i].texcoors2;
91
+        }
92
+
93
+        delete [] mTris;
94
+    }
95
+
96
+    if (mQuads)
97
+    {
98
+        for (i = 0; i < mNumQuads; ++i)
99
+        {
100
+            if (mQuads[i].quads)
101
+                delete [] mQuads[i].quads;
102
+
103
+            if (mQuads[i].alpha_quads)
104
+                delete [] mQuads[i].alpha_quads;
105
+
106
+            if (mQuads[i].texcoors)
107
+                delete [] mQuads[i].texcoors;
108
+
109
+            if (mQuads[i].texcoors2)
110
+                delete [] mQuads[i].texcoors2;
111
+        }
112
+
113
+        delete [] mQuads;
114
+    }
115
+
116
+    if (mVertexArray)
117
+    {
118
+        delete [] mVertexArray;
119
+    }
120
+
121
+    if (mNormalArray)
122
+    {
123
+        delete [] mNormalArray;
124
+    }
125
+
126
+    if (mColorArray)
127
+    {
128
+        delete [] mColorArray;
129
+    }
130
+
131
+    if (mTriangleTextures)
132
+    {
133
+        delete [] mTriangleTextures;
134
+    }
135
+
136
+    if (mTriangleIndices)
137
+    {
138
+        delete [] mTriangleIndices;
139
+    }
140
+
141
+    if (mTriangleFlags)
142
+    {
143
+        delete [] mTriangleFlags;
144
+    }
145
+
146
+    if (mTriangleTexCoordArray)
147
+    {
148
+        delete [] mTriangleTexCoordArray;
149
+    }
150
+}
151
+
152
+
153
+////////////////////////////////////////////////////////////
154
+// Public Accessors
155
+////////////////////////////////////////////////////////////
156
+
157
+void Mesh::drawAlpha()
158
+{
159
+    unsigned int i, j, k, index;
160
+
161
+
162
+    // Render quadralaterals
163
+    for (mQuads ? i = 0 : i = mNumQuads; i < mNumQuads; ++i)
164
+    {
165
+        switch (mMode)
166
+        {
167
+            case MeshModeWireframe:
168
+                glColor3f(0.0, 0.0, 1.0);
169
+                glBindTexture(GL_TEXTURE_2D, 0);
170
+                break;
171
+            case MeshModeSolid:
172
+                // Bind WHITE texture for solid colors
173
+                glBindTexture(GL_TEXTURE_2D, 0);
174
+                break;
175
+            case MeshModeTexture:
176
+            case MeshModeMultiTexture:
177
+                // Bind texture id for textures
178
+                glBindTexture(GL_TEXTURE_2D, mQuads[i].texture+1);
179
+                break;
180
+        }
181
+
182
+        glBegin(GL_QUADS);
183
+
184
+        for (j = 0; j < mQuads[i].num_alpha_quads; ++j)
185
+        {
186
+            for (k = 0; k < 4; ++k)
187
+            {
188
+                index = mQuads[i].alpha_quads[j*4+k];
189
+
190
+                glTexCoord2fv(mQuads[i].texcoors2[j*4+k]);
191
+                glColor4fv(mColors[index]);
192
+                glVertex3fv(mVertices[index]);
193
+            }
194
+        }
195
+
196
+        glEnd();
197
+    }
198
+
199
+    // Render triangles
200
+    for (mTris ? i = 0 : i = mNumTris; i < mNumTris; ++i)
201
+    {
202
+        switch (mMode)
203
+        {
204
+            case MeshModeWireframe:
205
+                glColor3f(0.0, 1.0, 0.0);
206
+                glBindTexture(GL_TEXTURE_2D, 0);
207
+                break;
208
+            case MeshModeSolid:
209
+                // Bind WHITE texture for solid colors
210
+                glBindTexture(GL_TEXTURE_2D, 0);
211
+                break;
212
+            case MeshModeTexture:
213
+            case MeshModeMultiTexture:
214
+                // Bind texture id for textures
215
+                glBindTexture(GL_TEXTURE_2D, mTris[i].texture+1);
216
+                break;
217
+        }
218
+
219
+        glBegin(GL_TRIANGLES);
220
+
221
+        for (j = 0; j < mTris[i].num_alpha_triangles; ++j)
222
+        {
223
+            for (k = 0; k < 3; ++k)
224
+            {
225
+                index = mTris[i].alpha_triangles[j*3+k];
226
+
227
+                glTexCoord2fv(mTris[i].texcoors2[j*3+k]);
228
+                glColor4fv(mColors[index]);
229
+                glVertex3fv(mVertices[index]);
230
+            }
231
+        }
232
+
233
+        glEnd();
234
+    }
235
+}
236
+
237
+
238
+void Mesh::drawSolid()
239
+{
240
+    unsigned int i, j, k, index;
241
+
242
+
243
+    if (mFlags & fMesh_UseVertexArray)
244
+    {
245
+        //glEnableClientState(GL_VERTEX_ARRAY);
246
+        //glVertexPointer(3, GL_FLOAT, 0, mVertexArray);
247
+
248
+        glPointSize(2.0f);
249
+        glColor3f(1.0f, 1.0f, 1.0f);
250
+        glBegin(GL_TRIANGLES);
251
+
252
+        for (i = 0; i < mTriangleCount*3; ++i)
253
+        {
254
+            //glArrayElement(mTriangleIndices[i]);
255
+            glVertex3fv(mVertexArray+mTriangleIndices[i]);
256
+        }
257
+
258
+        glEnd();
259
+
260
+        glPointSize(1.0f);
261
+
262
+        //! \fixme
263
+        /*
264
+        for (j = 0; j < mQuads[i].num_quads; ++j)
265
+        {
266
+            for (k = 0; k < 4; ++k)
267
+            {
268
+                index = mQuads[i].quads[j*4+k];
269
+
270
+                glTexCoord2fv(mQuads[i].texcoors[j*4+k]);
271
+                glArrayElement(mQuads[i].quads[j*4+k]);
272
+            }
273
+        }
274
+        */
275
+
276
+        return;
277
+    }
278
+
279
+    // Render quadralaterals
280
+    for (mQuads ? i = 0 : i = mNumQuads; i < mNumQuads; ++i)
281
+    {
282
+        switch (mMode)
283
+        {
284
+            case MeshModeSolid:
285
+                glColor3f(0.0, 0.0, 0.0);
286
+                break;
287
+            case MeshModeWireframe:
288
+                // Bind WHITE texture for solid colors
289
+                glBindTexture(GL_TEXTURE_2D, 0);
290
+                break;
291
+#ifdef MULTITEXTURE
292
+            case MeshModeMultiTexture:
293
+                glActiveTextureARB(GL_TEXTURE0_ARB);
294
+                glEnable(GL_TEXTURE_2D);
295
+                glBindTexture(GL_TEXTURE_2D, mQuads[i].texture+1);
296
+
297
+                glActiveTextureARB(GL_TEXTURE1_ARB);
298
+                glEnable(GL_TEXTURE_2D);
299
+                glBindTexture(GL_TEXTURE_2D, mQuads[i].bumpmap+1);
300
+                break;
301
+#else
302
+            case MeshModeMultiTexture:
303
+#endif
304
+            case MeshModeTexture:
305
+                // Bind texture id for textures
306
+                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
307
+                glBindTexture(GL_TEXTURE_2D, mQuads[i].texture+1);
308
+                break;
309
+        }
310
+
311
+        glBegin(GL_QUADS);
312
+
313
+        for (j = 0; j < mQuads[i].num_quads; ++j)
314
+        {
315
+            for (k = 0; k < 4; ++k)
316
+            {
317
+                index = mQuads[i].quads[j*4+k];
318
+
319
+                glColor4fv(mColors[index]);
320
+
321
+#ifdef MULTITEXTURE
322
+                if (mMode == MeshModeMultiTexture)
323
+                {
324
+                    glMultiTexCoord2fvARB(GL_TEXTURE0_ARB,
325
+                            mQuads[i].texcoors[j*4+k]);
326
+                    glMultiTexCoord2fvARB(GL_TEXTURE1_ARB,
327
+                            mQuads[i].texcoors[j*4+k]);
328
+                }
329
+                else
330
+#endif
331
+                    glTexCoord2fv(mQuads[i].texcoors[j*4+k]);
332
+
333
+                glVertex3fv(mVertices[index]);
334
+            }
335
+        }
336
+
337
+        glEnd();
338
+    }
339
+
340
+    // Render triangles
341
+    for (mTris ? i = 0 : i = mNumTris; i < mNumTris; ++i)
342
+    {
343
+        switch (mMode)
344
+        {
345
+            case MeshModeSolid:
346
+                glColor3f(1.0, 0.0, 0.0);
347
+                break;
348
+            case MeshModeWireframe:
349
+                // Bind WHITE texture for solid colors
350
+                glBindTexture(GL_TEXTURE_2D, 0);
351
+                break;
352
+#ifdef MULTITEXTURE
353
+            case MeshModeMultiTexture:
354
+                glActiveTextureARB(GL_TEXTURE0_ARB);
355
+                glEnable(GL_TEXTURE_2D);
356
+                glBindTexture(GL_TEXTURE_2D, mTris[i].texture+1);
357
+
358
+                glActiveTextureARB(GL_TEXTURE1_ARB);
359
+                glEnable(GL_TEXTURE_2D);
360
+                glBindTexture(GL_TEXTURE_2D, mTris[i].bumpmap+1);
361
+                break;
362
+#else
363
+            case MeshModeMultiTexture:
364
+#endif
365
+            case MeshModeTexture:
366
+                // Bind texture id for textures
367
+                glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
368
+                glBindTexture(GL_TEXTURE_2D, mTris[i].texture+1);
369
+                break;
370
+        }
371
+
372
+        glBegin(GL_TRIANGLES);
373
+
374
+        for (j = 0; j < mTris[i].num_triangles; ++j)
375
+        {
376
+            for (k = 0; k < 3; ++k)
377
+            {
378
+                index = mTris[i].triangles[j*3+k];
379
+
380
+#ifdef MULTITEXTURE
381
+                if (mMode == MeshModeMultiTexture)
382
+                {
383
+                    glMultiTexCoord2fvARB(GL_TEXTURE0_ARB,
384
+                            mTris[i].texcoors[j*3+k]);
385
+                    glMultiTexCoord2fvARB(GL_TEXTURE1_ARB,
386
+                            mTris[i].texcoors[j*3+k]);
387
+                }
388
+                else
389
+#endif
390
+                    glTexCoord2fv(mTris[i].texcoors[j*3+k]);
391
+
392
+                glColor4fv(mColors[index]);
393
+                glVertex3fv(mVertices[index]);
394
+            }
395
+        }
396
+
397
+        glEnd();
398
+    }
399
+
400
+#ifdef MULTITEXTURE
401
+    if (mMode == MeshModeMultiTexture)
402
+    {
403
+        glDisable(GL_TEXTURE_2D);
404
+        glActiveTextureARB(GL_TEXTURE0_ARB);
405
+    }
406
+#endif
407
+}
408
+
409
+
410
+////////////////////////////////////////////////////////////
411
+// Public Mutators
412
+////////////////////////////////////////////////////////////
413
+
414
+void Mesh::allocateColors(unsigned int n)
415
+{
416
+    if (mColors)
417
+    {
418
+        mNumColors = 0;
419
+        delete [] mColors;
420
+    }
421
+
422
+    if (!n)
423
+    {
424
+        return;
425
+    }
426
+
427
+    mNumColors = n;
428
+    mColors = new vec4_t[mNumColors];
429
+}
430
+
431
+
432
+void Mesh::allocateNormals(unsigned int n)
433
+{
434
+    if (mNormals)
435
+    {
436
+        mNumNormals = 0;
437
+        delete [] mNormals;
438
+    }
439
+
440
+    if (!n)
441
+    {
442
+        return;
443
+    }
444
+
445
+    mNumNormals = n;
446
+    mNormals = new vec3_t[mNumNormals];
447
+}
448
+
449
+
450
+void Mesh::allocateRectangles(unsigned int n)
451
+{
452
+    if (mQuads)
453
+    {
454
+        mNumQuads = 0;
455
+        delete [] mQuads;
456
+    }
457
+
458
+    if (!n)
459
+    {
460
+        return;
461
+    }
462
+
463
+    mNumQuads = n;
464
+    mQuads = new rect_t[mNumQuads];
465
+}
466
+
467
+
468
+void Mesh::allocateTriangles(unsigned int n)
469
+{
470
+    if (mTris)
471
+    {
472
+        mNumTris = 0;
473
+        delete [] mTris;
474
+    }
475
+
476
+    if (!n)
477
+    {
478
+        return;
479
+    }
480
+
481
+    mNumTris = n;
482
+    mTris = new tris_t[mNumTris];
483
+}
484
+
485
+
486
+void Mesh::allocateVertices(unsigned int n)
487
+{
488
+    if (mVertices)
489
+    {
490
+        mNumVertices = 0;
491
+        delete [] mVertices;
492
+    }
493
+
494
+    if (!n)
495
+    {
496
+        return;
497
+    }
498
+
499
+    mNumVertices = n;
500
+    mVertices = new vec3_t[mNumVertices];
501
+}
502
+
503
+
504
+void Mesh::bufferColorArray(unsigned int colorCount, vec_t *colors)
505
+{
506
+    if (mColors)
507
+    {
508
+        mNumColors = 0;
509
+        delete [] mColors;
510
+    }
511
+
512
+    if (!colorCount)
513
+    {
514
+        return;
515
+    }
516
+
517
+    mNumColors = colorCount;
518
+    mColorArray = colors;
519
+}
520
+
521
+
522
+void Mesh::bufferNormalArray(unsigned int normalCount, vec_t *normals)
523
+{
524
+    if (mNormals)
525
+    {
526
+        mNumNormals = 0;
527
+        delete [] mNormals;
528
+    }
529
+
530
+    if (!normalCount)
531
+    {
532
+        return;
533
+    }
534
+
535
+    mNumNormals = normalCount;
536
+    mNormalArray = normals;
537
+}
538
+
539
+
540
+void Mesh::bufferTriangles(unsigned int count,
541
+        unsigned int *indices, vec_t *texCoords,
542
+        int *textures, unsigned int *flags)
543
+{
544
+
545
+    mTriangleCount = count;
546
+    mTriangleTextures = textures;
547
+    mTriangleIndices = indices;
548
+    mTriangleFlags = flags;
549
+    mTriangleTexCoordArray = texCoords;
550
+
551
+    //! \fixme sortTrianglesByTexture();
552
+}
553
+
554
+
555
+void Mesh::bufferVertexArray(unsigned int vertexCount, vec_t *vertices)
556
+{
557
+    if (mVertices)
558
+    {
559
+        mNumVertices = 0;
560
+        delete [] mVertices;
561
+    }
562
+
563
+    if (!vertexCount)
564
+    {
565
+        return;
566
+    }
567
+
568
+    mNumVertices = vertexCount;
569
+    mVertexArray = vertices;
570
+    mFlags |= fMesh_UseVertexArray;
571
+}
572
+
573
+
574
+void Mesh::setColor(unsigned int index,
575
+        float r, float g, float b, float a)
576
+{
577
+    assert(index < mNumColors);
578
+
579
+    mColors[index][0] = r;
580
+    mColors[index][1] = g;
581
+    mColors[index][2] = b;
582
+    mColors[index][3] = a;
583
+}
584
+
585
+
586
+void Mesh::setColor(unsigned int index, float rgba[4])
587
+{
588
+    assert(index < mNumColors);
589
+
590
+    mColors[index][0] = rgba[0];
591
+    mColors[index][1] = rgba[1];
592
+    mColors[index][2] = rgba[2];
593
+    mColors[index][3] = rgba[3];
594
+}
595
+
596
+
597
+void Mesh::setNormal(unsigned int index, float i, float j, float k)
598
+{
599
+    assert(index < mNumNormals);
600
+
601
+    mNormals[index][0] = i;
602
+    mNormals[index][1] = j;
603
+    mNormals[index][2] = k;
604
+}
605
+
606
+
607
+void Mesh::setVertex(unsigned int index, float x, float y, float z)
608
+{
609
+    assert(index < mNumVertices);
610
+
611
+    mVertices[index][0] = x;
612
+    mVertices[index][1] = y;
613
+    mVertices[index][2] = z;
614
+}
615
+
616
+
617
+////////////////////////////////////////////////////////////
618
+// Private Accessors
619
+////////////////////////////////////////////////////////////
620
+
621
+
622
+////////////////////////////////////////////////////////////
623
+// Private Mutators
624
+////////////////////////////////////////////////////////////
625
+

+ 162
- 0
src/Particle.cpp Ver fichero

@@ -0,0 +1,162 @@
1
+/*!
2
+ * \file src/Particle.cpp
3
+ * \brief Particle system base implementation
4
+ *
5
+ * \author Mongoose
6
+ */
7
+
8
+#include <stdlib.h>
9
+#include <stdio.h>
10
+#include <assert.h>
11
+
12
+#include "Particle.h"
13
+
14
+Particle::Particle()
15
+{
16
+    setActive(true);
17
+    TextureId(0);
18
+    Speed(2000.0f, 2000.0f, 2000.0f);
19
+    Color(1.0f, 1.0f, 1.0f);
20
+    Force(0.0f, 0.8f, 0.0f);
21
+
22
+    Reset();
23
+}
24
+
25
+
26
+void Particle::TextureId(int id)
27
+{
28
+    _texture = id;
29
+}
30
+
31
+
32
+void Particle::setActive(bool active)
33
+{
34
+    _active = active;
35
+}
36
+
37
+
38
+void Particle::Speed(float x, float y, float z)
39
+{
40
+    _speed[0] = x;
41
+    _speed[1] = y;
42
+    _speed[2] = z;
43
+}
44
+
45
+
46
+void Particle::Color(float r, float g, float b)
47
+{
48
+    _color[0] = r;
49
+    _color[1] = g;
50
+    _color[2] = b;
51
+}
52
+
53
+
54
+void Particle::Force(float x, float y, float z)
55
+{
56
+    _force[0] = x;
57
+    _force[1] = y;
58
+    _force[2] = z;
59
+}
60
+
61
+
62
+void Particle::Reset()
63
+{
64
+    // Mongoose 2002.01.01, Ah, how old is that code?
65
+#ifdef OBSOLETE
66
+    _active = true;
67
+    _life = 1.0;
68
+    _blend = (float)(rand() % 100) / 1000.0 + 0.003;
69
+
70
+    _pos[0] = _pos[1] = _pos[2] = 0.0;
71
+
72
+    _dir[0] = (float)((rand() % 50) - 26.0) * 10.0;
73
+    _dir[1] = (float)((rand() % 50) - 25.0) * 10.0;
74
+    _dir[2] = _dir[1];
75
+
76
+    _force[0] = 0.0;
77
+    _force[1] = -0.8;
78
+    _force[2] = 0.0;
79
+#else
80
+    //! \fixme _blend prob should have nonstatic range
81
+    _blend = (float)(0.003 + (0.1 * rand() / (RAND_MAX + 1.0))); // high order
82
+    //_blend = (float)(rand() % 100) / 1000.0 + 0.003;
83
+
84
+    //! \fixme Reset these using some nonstatic functions and values later
85
+    _life = 1.0;
86
+
87
+    _pos[0] = _pos[1] = _pos[2] = 0.0;
88
+
89
+    _dir[0] = (float)(-26.0 + (50.0 * rand() / (RAND_MAX + 1.0))); // high order
90
+    _dir[0] *= 10.0;
91
+    //_dir[0] = (float)((rand() % 50) - 26.0) * 10.0;
92
+    _dir[1] = (float)(-25.0 + (50.0 * rand() / (RAND_MAX + 1.0))); // high order
93
+    _dir[1] *= 10.0;
94
+    //_dir[1] = (float)((rand() % 50) - 25.0) * 10.0;
95
+    _dir[2] = _dir[1];
96
+#endif
97
+}
98
+
99
+
100
+void Particle::Pos(float *x, float *y, float *z)
101
+{
102
+    assert(x != NULL);
103
+    assert(y != NULL);
104
+    assert(z != NULL);
105
+
106
+    *x = _pos[0];
107
+    *y = _pos[1];
108
+    *z = _pos[2];
109
+}
110
+
111
+
112
+void Particle::Color(float *r, float *g, float *b)
113
+{
114
+    assert(r != NULL);
115
+    assert(g != NULL);
116
+    assert(b != NULL);
117
+
118
+    *r = _color[0];
119
+    *g = _color[1];
120
+    *b = _color[2];
121
+}
122
+
123
+
124
+float Particle::Life()
125
+{
126
+    return _life;
127
+}
128
+
129
+
130
+void Particle::Update()
131
+{
132
+    // Adjust particle position
133
+    _pos[0] += _dir[0] / _speed[0];
134
+    _pos[1] += _dir[1] / _speed[1];
135
+    _pos[2] += _dir[2] / _speed[2];
136
+
137
+    // Adjust particle direction
138
+    _dir[0] += _force[0];
139
+    _dir[1] += _force[1];
140
+    _dir[2] += _force[2];
141
+
142
+    // Adjust particle blending/life
143
+    _life -= _blend;
144
+
145
+    // Reset 'dead' OR fully blended particles
146
+    if (_life < 0.0)
147
+    {
148
+        Reset();
149
+    }
150
+}
151
+
152
+
153
+int Particle::Texture()
154
+{
155
+    return _texture;
156
+}
157
+
158
+
159
+bool Particle::isActive()
160
+{
161
+    return _active;
162
+}

+ 270
- 0
src/ViewVolume.cpp Ver fichero

@@ -0,0 +1,270 @@
1
+/*!
2
+ * \file include/ViewVolume.h
3
+ * \brief Viewing Volume for culling use
4
+ *
5
+ * Thanks Mark Morley for the article I used to get several algorithms.
6
+ *
7
+ * \author Mongoose
8
+ */
9
+
10
+#include <math.h>
11
+
12
+#include "ViewVolume.h"
13
+
14
+ViewVolume::ViewVolume() {
15
+    mFrustum[0][0] = mFrustum[0][1] = mFrustum[0][2] = mFrustum[0][3] = 0.0f;
16
+    mFrustum[1][0] = mFrustum[1][1] = mFrustum[1][2] = mFrustum[1][3] = 0.0f;
17
+    mFrustum[2][0] = mFrustum[2][1] = mFrustum[2][2] = mFrustum[2][3] = 0.0f;
18
+    mFrustum[3][0] = mFrustum[3][1] = mFrustum[3][2] = mFrustum[3][3] = 0.0f;
19
+    mFrustum[4][0] = mFrustum[4][1] = mFrustum[4][2] = mFrustum[4][3] = 0.0f;
20
+    mFrustum[5][0] = mFrustum[5][1] = mFrustum[5][2] = mFrustum[5][3] = 0.0f;
21
+}
22
+
23
+bool ViewVolume::isBoundingVolumeInFrustum(BoundingVolume bvol) {
24
+    return (isBoundingSphereInFrustum(bvol.mSphere) &&
25
+            isBoundingBoxInFrustum(bvol.mBox));
26
+}
27
+
28
+bool ViewVolume::isBoundingSphereInFrustum(BoundingSphere bvol) {
29
+    return (isSphereInFrustum(bvol.mCenter[0],
30
+                bvol.mCenter[1],
31
+                bvol.mCenter[2],
32
+                bvol.mRadius));
33
+}
34
+
35
+bool ViewVolume::isBoundingBoxInFrustum(BoundingBox bvol) {
36
+    return (isBboxInFrustum(bvol.mMin, bvol.mMax));
37
+}
38
+
39
+bool ViewVolume::isPointInFrustum(vec_t x, vec_t y, vec_t z) {
40
+    for (unsigned int p = 0; p < 6; ++p) {
41
+        if (mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z +
42
+                mFrustum[p][3] <= 0) {
43
+            return false;
44
+        }
45
+    }
46
+    return true;
47
+}
48
+
49
+bool ViewVolume::isSphereInFrustum(vec_t x, vec_t y, vec_t z, vec_t radius) {
50
+    vec_t d;
51
+    for (unsigned int p = 0; p < 6; ++p) {
52
+        d = mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z + mFrustum[p][3];
53
+        if (d <= -radius)
54
+            return false;
55
+    }
56
+    return true;
57
+}
58
+
59
+bool ViewVolume::isBboxInFrustum(vec3_t min, vec3_t max) {
60
+    for (unsigned int p = 0; p < 6; ++p) {
61
+        if (mFrustum[p][0] * min[0] +
62
+                mFrustum[p][1] * min[1] +
63
+                mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
64
+            continue;
65
+
66
+        if (mFrustum[p][0] * max[0] +
67
+                mFrustum[p][1] * max[1] +
68
+                mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
69
+            continue;
70
+
71
+        if (mFrustum[p][0] * min[0] +
72
+                mFrustum[p][1] * max[1] +
73
+                mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
74
+            continue;
75
+
76
+        if (mFrustum[p][0] * min[0] +
77
+                mFrustum[p][1] * min[1] +
78
+                mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
79
+            continue;
80
+
81
+        if (mFrustum[p][0] * min[0] +
82
+                mFrustum[p][1] * max[1] +
83
+                mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
84
+            continue;
85
+
86
+        if (mFrustum[p][0] * max[0] +
87
+                mFrustum[p][1] * min[1] +
88
+                mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
89
+            continue;
90
+
91
+        if (mFrustum[p][0] * max[0] +
92
+                mFrustum[p][1] * max[1] +
93
+                mFrustum[p][2] * min[2] + mFrustum[p][3] > 0)
94
+            continue;
95
+
96
+        if (mFrustum[p][0] * max[0] +
97
+                mFrustum[p][1] * min[1] +
98
+                mFrustum[p][2] * max[2] + mFrustum[p][3] > 0)
99
+            continue;
100
+
101
+        return false;
102
+    }
103
+    return true;
104
+}
105
+
106
+vec_t ViewVolume::getDistToSphereFromNear(vec_t x, vec_t y, vec_t z, vec_t radius) {
107
+    vec_t d = 0.0;
108
+    for (unsigned int p = 0; p < 6; ++p) {
109
+        d = mFrustum[p][0] * x + mFrustum[p][1] * y + mFrustum[p][2] * z + mFrustum[p][3];
110
+        if (d <= -radius)
111
+            return 0;
112
+    }
113
+    return d + radius;
114
+}
115
+
116
+vec_t ViewVolume::getDistToBboxFromNear(vec3_t min, vec3_t max) {
117
+    vec3_t center;
118
+    vec_t d, radius;
119
+
120
+    midpoint(min, max, center);
121
+
122
+    // 5 should be near plane
123
+    d = (mFrustum[5][0] * center[0] +
124
+            mFrustum[5][1] * center[1] +
125
+            mFrustum[5][2] * center[2] +
126
+            mFrustum[5][3]);
127
+
128
+    radius = distance(max, center);
129
+
130
+    if (d <= -radius)
131
+        return 0;
132
+
133
+    return d + radius;
134
+}
135
+
136
+void ViewVolume::getFrustum(vec_t frustum[6][4]) {
137
+    for (unsigned int p = 0; p < 6; ++p) {
138
+        for (unsigned int i = 0; i < 4; ++i) {
139
+            frustum[p][i] = mFrustum[p][i];
140
+        }
141
+    }
142
+}
143
+
144
+void ViewVolume::getPlane(ViewVolumeSide p, vec4_t plane) {
145
+    for (unsigned int i = 0; i < 4; ++i) {
146
+        plane[i] =  mFrustum[p][i];
147
+    }
148
+}
149
+
150
+void ViewVolume::updateFrame(matrix_t proj, matrix_t mdl) {
151
+    setModel(mdl);
152
+    setProjection(proj);
153
+    updateClip();
154
+    updateFrustum();
155
+}
156
+
157
+void ViewVolume::updateFrame() {
158
+    updateClip();
159
+    updateFrustum();
160
+}
161
+
162
+void ViewVolume::setModel(matrix_t mdl) {
163
+    mModel.setMatrix(mdl);
164
+}
165
+
166
+void ViewVolume::setProjection(matrix_t proj) {
167
+    mProjection.setMatrix(proj);
168
+}
169
+
170
+void ViewVolume::updateClip() {
171
+    mClip = mProjection * mModel;
172
+}
173
+
174
+void ViewVolume::updateFrustum() {
175
+    matrix_t clip;
176
+    vec_t t;
177
+
178
+    mClip.getMatrix(clip);
179
+
180
+    /* Extract the numbers for the RIGHT plane */
181
+    mFrustum[0][0] = clip[ 3] - clip[ 0];
182
+    mFrustum[0][1] = clip[ 7] - clip[ 4];
183
+    mFrustum[0][2] = clip[11] - clip[ 8];
184
+    mFrustum[0][3] = clip[15] - clip[12];
185
+
186
+    /* Normalize the result */
187
+    t = sqrtf(mFrustum[0][0] * mFrustum[0][0] +
188
+            mFrustum[0][1] * mFrustum[0][1] +
189
+            mFrustum[0][2] * mFrustum[0][2]);
190
+    mFrustum[0][0] /= t;
191
+    mFrustum[0][1] /= t;
192
+    mFrustum[0][2] /= t;
193
+    mFrustum[0][3] /= t;
194
+
195
+    /* Extract the numbers for the LEFT plane */
196
+    mFrustum[1][0] = clip[ 3] + clip[ 0];
197
+    mFrustum[1][1] = clip[ 7] + clip[ 4];
198
+    mFrustum[1][2] = clip[11] + clip[ 8];
199
+    mFrustum[1][3] = clip[15] + clip[12];
200
+
201
+    /* Normalize the result */
202
+    t = sqrtf(mFrustum[1][0] * mFrustum[1][0] +
203
+            mFrustum[1][1] * mFrustum[1][1] +
204
+            mFrustum[1][2] * mFrustum[1][2]);
205
+    mFrustum[1][0] /= t;
206
+    mFrustum[1][1] /= t;
207
+    mFrustum[1][2] /= t;
208
+    mFrustum[1][3] /= t;
209
+
210
+    /* Extract the BOTTOM plane */
211
+    mFrustum[2][0] = clip[ 3] + clip[ 1];
212
+    mFrustum[2][1] = clip[ 7] + clip[ 5];
213
+    mFrustum[2][2] = clip[11] + clip[ 9];
214
+    mFrustum[2][3] = clip[15] + clip[13];
215
+
216
+    /* Normalize the result */
217
+    t = sqrtf(mFrustum[2][0] * mFrustum[2][0] +
218
+            mFrustum[2][1] * mFrustum[2][1] +
219
+            mFrustum[2][2] * mFrustum[2][2]);
220
+    mFrustum[2][0] /= t;
221
+    mFrustum[2][1] /= t;
222
+    mFrustum[2][2] /= t;
223
+    mFrustum[2][3] /= t;
224
+
225
+    /* Extract the TOP plane */
226
+    mFrustum[3][0] = clip[ 3] - clip[ 1];
227
+    mFrustum[3][1] = clip[ 7] - clip[ 5];
228
+    mFrustum[3][2] = clip[11] - clip[ 9];
229
+    mFrustum[3][3] = clip[15] - clip[13];
230
+
231
+    /* Normalize the result */
232
+    t = sqrtf(mFrustum[3][0] * mFrustum[3][0] +
233
+            mFrustum[3][1] * mFrustum[3][1] +
234
+            mFrustum[3][2] * mFrustum[3][2]);
235
+    mFrustum[3][0] /= t;
236
+    mFrustum[3][1] /= t;
237
+    mFrustum[3][2] /= t;
238
+    mFrustum[3][3] /= t;
239
+
240
+    /* Extract the FAR plane */
241
+    mFrustum[4][0] = clip[ 3] - clip[ 2];
242
+    mFrustum[4][1] = clip[ 7] - clip[ 6];
243
+    mFrustum[4][2] = clip[11] - clip[10];
244
+    mFrustum[4][3] = clip[15] - clip[14];
245
+
246
+    /* Normalize the result */
247
+    t = sqrtf(mFrustum[4][0] * mFrustum[4][0] +
248
+            mFrustum[4][1] * mFrustum[4][1] +
249
+            mFrustum[4][2] * mFrustum[4][2]);
250
+    mFrustum[4][0] /= t;
251
+    mFrustum[4][1] /= t;
252
+    mFrustum[4][2] /= t;
253
+    mFrustum[4][3] /= t;
254
+
255
+    /* Extract the NEAR plane */
256
+    mFrustum[5][0] = clip[ 3] + clip[ 2];
257
+    mFrustum[5][1] = clip[ 7] + clip[ 6];
258
+    mFrustum[5][2] = clip[11] + clip[10];
259
+    mFrustum[5][3] = clip[15] + clip[14];
260
+
261
+    /* Normalize the result */
262
+    t = sqrtf(mFrustum[5][0] * mFrustum[5][0] +
263
+            mFrustum[5][1] * mFrustum[5][1] +
264
+            mFrustum[5][2] * mFrustum[5][2]);
265
+    mFrustum[5][0] /= t;
266
+    mFrustum[5][1] /= t;
267
+    mFrustum[5][2] /= t;
268
+    mFrustum[5][3] /= t;
269
+}
270
+

Loading…
Cancelar
Guardar