Просмотр исходного кода

Added World, WorldData, using std list and vector.

Thomas Buck 10 лет назад
Родитель
Сommit
54741ed7bd
4 измененных файлов: 1176 добавлений и 0 удалений
  1. 194
    0
      include/World.h
  2. 214
    0
      include/WorldData.h
  3. 1
    0
      src/CMakeLists.txt
  4. 767
    0
      src/World.cpp

+ 194
- 0
include/World.h Просмотреть файл

@@ -0,0 +1,194 @@
1
+/*!
2
+ * \file include/World.h
3
+ * \brief The game world (model)
4
+ *
5
+ * \author Mongoose
6
+ * \author xythobuz
7
+ */
8
+
9
+#ifndef _WORLD_H_
10
+#define _WORLD_H_
11
+
12
+#include <list>
13
+#include <vector>
14
+
15
+#define BAD_BLOOD  //!< \todo For temp rendering use
16
+
17
+#ifdef BAD_BLOOD
18
+#include "SkeletalModel.h"
19
+#endif
20
+
21
+#include "WorldData.h"
22
+
23
+/*!
24
+ * \brief The game world (model)
25
+ */
26
+class World {
27
+public:
28
+
29
+    enum WorldFlag {
30
+        fEnableHopping = 1
31
+    };
32
+
33
+    /*!
34
+     * \brief Constructs an object of World
35
+     */
36
+    World();
37
+
38
+    /*!
39
+     * \brief Deconstructs an object of World
40
+     */
41
+    ~World();
42
+
43
+    /*!
44
+     * \brief Find room a location is in.
45
+     *
46
+     * If it fails to be in a room it gives closest overlapping room.
47
+     * \param index Guessed room index
48
+     * \param x X coordinate
49
+     * \param y Y coordinate
50
+     * \param z Z coordinate
51
+     * \returns correct room index or -1 for unknown
52
+     */
53
+    int getRoomByLocation(int index, float x, float y, float z);
54
+
55
+    /*!
56
+     * \brief Find room a location is in.
57
+     *
58
+     * If it fails to be in a room it gives closest overlapping room.
59
+     * \param x X coordinate
60
+     * \param y Y coordinate
61
+     * \param z Z coordinate
62
+     * \returns correct room index or -1 for unknown
63
+     */
64
+    int getRoomByLocation(float x, float y, float z);
65
+
66
+    /*!
67
+     * \brief Looks for portal crossings from xyz to xyz2 segment
68
+     * from room[index]
69
+     * \param index valid room index
70
+     * \param x X coordinate of first point
71
+     * \param y Y coordinate of first point
72
+     * \param z Z coordinate of first point
73
+     * \param x2 X coordinate of second point
74
+     * \param y2 Y coordinate of second point
75
+     * \param z2 Z coordinate of second point
76
+     * \returns index of adjoined room or -1
77
+     */
78
+    int getAdjoiningRoom(int index,
79
+                            float x, float y, float z,
80
+                            float x2, float y2, float z2);
81
+
82
+    /*!
83
+     * \brief Gets the sector index of the position in room
84
+     * \param room valid room index
85
+     * \param x X coordinate in room
86
+     * \param z Z coordinate in room
87
+     * \returns sector index of position in room
88
+     */
89
+    int getSector(int room, float x, float z);
90
+    int getSector(int room, float x, float z, float *floor, float *ceiling);
91
+
92
+    unsigned int getRoomInfo(int room);
93
+
94
+    /*!
95
+     * \brief Check if sector is a wall
96
+     * \param room valid room index
97
+     * \param sector valid sector index
98
+     * \returns true if this sector is a wall
99
+     */
100
+    bool isWall(int room, int sector);
101
+
102
+    /*!
103
+     * \brief Get the world height at a position
104
+     * \param index valid room index
105
+     * \param x X coordinate
106
+     * \param y will be set to world height in that room
107
+     * \param z Z coordinate
108
+     * \returns true if position is in a room
109
+     */
110
+    bool getHeightAtPosition(int index, float x, float *y, float z);
111
+
112
+#ifdef BAD_BLOOD
113
+    //! \todo Temp methods for rendering use until more refactoring is done
114
+    model_mesh_t *getMesh(int index);
115
+    skeletal_model_t *getModel(int index);
116
+    room_mesh_t *getRoom(int index);
117
+    std::vector<entity_t *> *getEntities();
118
+    std::vector<sprite_seq_t *> *getSprites();
119
+    std::vector<room_mesh_t *> *getRooms();
120
+#endif
121
+
122
+    /*!
123
+     * \brief Set an option flag
124
+     * \param flag flag to set
125
+     */
126
+    void setFlag(WorldFlag flag);
127
+
128
+    /*!
129
+     * \brief Clear an option flag
130
+     * \param flag flag to clear
131
+     */
132
+    void clearFlag(WorldFlag flag);
133
+
134
+    /*!
135
+     * \brief Clears all data in world
136
+     * \todo in future will check if data is in use before clearing
137
+     */
138
+    void destroy();
139
+
140
+    /*!
141
+     * \brief Adds room to world
142
+     * \param room room to add
143
+     */
144
+    void addRoom(room_mesh_t *room);
145
+
146
+    /*!
147
+     * \brief ADds mesh to world
148
+     * \param model mesh to add
149
+     */
150
+    void addMesh(model_mesh_t *model);
151
+
152
+    /*!
153
+     * \brief Adds entity to world
154
+     * \param e entity to add
155
+     */
156
+    void addEntity(entity_t *e);
157
+
158
+    /*!
159
+     * \brief Adds model to world.
160
+     * \param model model to add
161
+     * \returns next model ID or -1 on error
162
+     */
163
+    int addModel(skeletal_model_t *model);
164
+
165
+    /*!
166
+     * \brief Adds sprite to world
167
+     * \param sprite sprite to add
168
+     */
169
+    void addSprite(sprite_seq_t *sprite);
170
+
171
+    /*!
172
+     * \brief Move entity in given direction unless collision occurs
173
+     * \param e entity to move
174
+     * \param movement direction of movement ('f', 'b', 'l' or 'r')
175
+     */
176
+    void moveEntity(entity_t *e, char movement);
177
+
178
+private:
179
+
180
+    /*!
181
+     * \brief Clears all data in world
182
+     */
183
+    void clear();
184
+
185
+    bool mClearLock;
186
+    unsigned int mFlags;                //!< World flags
187
+    std::vector<entity_t *> mEntities;       //!< World entities
188
+    std::vector<room_mesh_t *> mRooms;       //!< Map data and meshes
189
+    std::vector<model_mesh_t *> mMeshes;     //!< Unanimated meshes
190
+    std::vector<sprite_seq_t *> mSprites;    //!< Sprites
191
+    std::vector<skeletal_model_t *> mModels; //!< Skeletal animation models
192
+};
193
+
194
+#endif

+ 214
- 0
include/WorldData.h Просмотреть файл

@@ -0,0 +1,214 @@
1
+/*!
2
+ * \file include/World.h
3
+ * \brief The game world (model)
4
+ *
5
+ * \author Mongoose
6
+ * \author xythobuz
7
+ */
8
+
9
+#ifndef _WORLDDATA_H_
10
+#define _WORLDDATA_H_
11
+
12
+#include "math/math.h"
13
+
14
+// Mirrors TombRaider class' room flags really
15
+typedef enum {
16
+    roomFlag_underWater    = 0x0001
17
+} room_flags_t;
18
+
19
+typedef enum {
20
+    worldMoveType_walkNoSwim   = -1,
21
+    worldMoveType_walk         = 0,
22
+    worldMoveType_noClipping   = 1,
23
+    worldMoveType_fly          = 2,
24
+    worldMoveType_swim         = 3
25
+} worldMoveType;
26
+
27
+typedef struct {
28
+    vec3_t pos;
29
+} vertex_t;
30
+
31
+/*
32
+typedef struct {
33
+    vec2_t uv;
34
+} uv_t;
35
+
36
+typedef struct {
37
+    vec4_t rgba;
38
+} color_t;
39
+*/
40
+
41
+typedef struct {
42
+    vec2_t st;
43
+} texel_t;
44
+
45
+typedef struct {
46
+    int num_verts;      //!< 4 == Quad, 3 == Triangle, rendered as triangles
47
+    vertex_t vertex[4];
48
+    texel_t texel[4];
49
+    float pos[3];
50
+    float radius;       //!< \fixme yeah, I know
51
+    int texture;
52
+} sprite_t;
53
+
54
+typedef struct {
55
+    int num_sprites;
56
+    sprite_t *sprite;
57
+} sprite_seq_t;
58
+
59
+/*! \fixme For now shaders are textures on tex objects
60
+ * and materials on color objects. If -1
61
+ * then it doesn't have that information yet.
62
+ */
63
+typedef struct {
64
+    int index[3];
65
+    vec_t st[6];
66
+    int texture;
67
+    unsigned short transparency;
68
+} texture_tri_t;
69
+
70
+typedef struct {
71
+    std::vector<texture_tri_t *> texturedTriangles;
72
+    std::vector<texture_tri_t *> coloredTriangles;
73
+    std::vector<texture_tri_t *> texturedRectangles;
74
+    std::vector<texture_tri_t *> coloredRectangles;
75
+
76
+    vec3_t center;
77
+    float radius;
78
+
79
+    unsigned int vertexCount;
80
+    vec_t *vertices;
81
+
82
+    unsigned int colorCount;
83
+    vec_t *colors;
84
+
85
+    unsigned int normalCount;
86
+    vec_t *normals;
87
+} model_mesh_t;
88
+
89
+typedef struct entity_s {
90
+    int id;                  //!< Unique identifier
91
+    float pos[3];            //!< World position
92
+    float angles[3];         //!< Euler angles (pitch, yaw, roll)
93
+    int type;                //!< {(0x00, item), (0x01, ai), (0x02, player)}
94
+    int room;                //!< Current room entity is in
95
+    worldMoveType moveType;  //!< Type of motion/clipping
96
+    bool moving;             //!< In motion?
97
+    struct entity_s *master; //!< Part of entity chain?
98
+
99
+    int state;               //!< State of the Player, AI, or object
100
+    int objectId;            //!< What kind of entity?
101
+
102
+    int modelId;             //!< Animation model
103
+    void *tmpHook;
104
+    bool animate;
105
+
106
+    /*
107
+    float time, lastTime;
108
+    int state, lastState;
109
+    int event, lastEvent;
110
+    int goal;
111
+    */
112
+} entity_t;
113
+
114
+typedef struct {
115
+    int index;    //!< model_mesh index
116
+    float yaw;    //!< angle of rotation on Y
117
+    float pos[3]; //!< position
118
+
119
+    //vec3_t bboxMax;
120
+    //vec3_t bboxMin;
121
+} static_model_t;
122
+
123
+typedef struct {
124
+    float vertices[4][3];
125
+    float normal[3];
126
+    int adjoining_room;
127
+} portal_t;
128
+
129
+typedef struct {
130
+    vertex_t a;
131
+    vertex_t b;
132
+    vertex_t c;
133
+    vertex_t d;
134
+} box_t;
135
+
136
+typedef struct {
137
+    vec_t floor;
138
+    vec_t ceiling;
139
+
140
+    bool wall;
141
+} sector_t;
142
+
143
+//! \fixme No room mesh list or sprites and etc
144
+typedef struct {
145
+    std::vector<int> adjacentRooms;
146
+    std::vector<portal_t *> portals;
147
+    std::vector<static_model_t *> models;
148
+    std::vector<sprite_t *> sprites;
149
+    std::vector<box_t *> boxes;
150
+    std::vector<sector_t *> sectors;
151
+
152
+    int id;
153
+    unsigned int flags;
154
+    unsigned int numXSectors;
155
+    unsigned int numZSectors;
156
+    float pos[3];
157
+    vec3_t bbox_min;
158
+    vec3_t bbox_max;
159
+} room_mesh_t;
160
+
161
+// Workout generic entity and a client class from these entities
162
+typedef struct world_entity_s {
163
+    vec3_t pos;
164
+    vec3_t lastPos;
165
+    vec3_t angle;
166
+    vec_t ttl;
167
+
168
+    int type;
169
+    int state;
170
+
171
+    //struct world_entity_s *master;
172
+
173
+} world_entity_t;
174
+
175
+typedef struct {
176
+    vec3_t pos;
177
+    vec3_t lastPos;
178
+    vec3_t angle;
179
+    char clipping;
180
+    float time, eventTime, eventTimer;
181
+    int state, nextState;
182
+    float health;
183
+
184
+    // Client
185
+    unsigned int uid;
186
+    char name[32];
187
+    int actor, enemy;
188
+
189
+    // Render
190
+    unsigned int model;
191
+    unsigned int skin;
192
+    unsigned int animFrame;
193
+
194
+} actor_entity_t;
195
+
196
+enum OpenRaiderEvent {
197
+    eNone = 0,
198
+    eWeaponDischarge,
199
+    eDying,
200
+    eDead,
201
+    eWounded,
202
+    eRunForward,
203
+    eRunBackward,
204
+    eJump,
205
+    eCrouchWalk,
206
+    eIdle,
207
+    eTaunt,
208
+    eTurn,
209
+    eRespawn,
210
+    eLand
211
+};
212
+
213
+#endif
214
+

+ 1
- 0
src/CMakeLists.txt Просмотреть файл

@@ -46,6 +46,7 @@ set (SRCS ${SRCS} "Texture.cpp")
46 46
 set (SRCS ${SRCS} "TombRaider.cpp")
47 47
 set (SRCS ${SRCS} "ViewVolume.cpp")
48 48
 set (SRCS ${SRCS} "Window.cpp")
49
+set (SRCS ${SRCS} "World.cpp")
49 50
 
50 51
 # Select available Windowing library
51 52
 if (SDL2_FOUND AND SDL2TTF_FOUND)

+ 767
- 0
src/World.cpp Просмотреть файл

@@ -0,0 +1,767 @@
1
+/*!
2
+ * \file src/World.cpp
3
+ * \brief The game world (model)
4
+ *
5
+ * \author Mongoose
6
+ */
7
+
8
+#include <math.h>
9
+
10
+#include "World.h"
11
+
12
+
13
+////////////////////////////////////////////////////////////
14
+// Constructors
15
+////////////////////////////////////////////////////////////
16
+
17
+World::World()
18
+{
19
+    mClearLock = false;
20
+    mFlags = 0;
21
+}
22
+
23
+
24
+World::~World()
25
+{
26
+    destroy();
27
+}
28
+
29
+
30
+////////////////////////////////////////////////////////////
31
+// Public Accessors
32
+////////////////////////////////////////////////////////////
33
+
34
+int World::getRoomByLocation(int index, float x, float y, float z)
35
+{
36
+    room_mesh_t *room = mRooms[index];
37
+
38
+    if (room)
39
+    {
40
+        if (x > room->bbox_min[0] && x < room->bbox_max[0] &&
41
+                z > room->bbox_min[2] && z < room->bbox_max[2])
42
+        {
43
+            if (y > room->bbox_min[1] && y < room->bbox_max[1])
44
+                return index;
45
+        }
46
+    }
47
+
48
+    return getRoomByLocation(x, y, z);
49
+}
50
+
51
+
52
+int World::getRoomByLocation(float x, float y, float z)
53
+{
54
+    room_mesh_t *room;
55
+    int hop = -1;
56
+
57
+
58
+    for(std::vector<int>::size_type i = 0; i != mRooms.size(); i++)
59
+    {
60
+        room = mRooms[i];
61
+
62
+        if (!room)
63
+            continue;
64
+
65
+        if (x > room->bbox_min[0] && x < room->bbox_max[0] &&
66
+                z > room->bbox_min[2] && z < room->bbox_max[2])
67
+        {
68
+            // This room contains current position
69
+            if (y > room->bbox_min[1] && y < room->bbox_max[1])
70
+                return i;
71
+
72
+            // This room is above or below current position
73
+            hop = i;
74
+        }
75
+    }
76
+
77
+    // Room is -1?  Must be in void, try to hop to room with same X,Z
78
+    if (mFlags & fEnableHopping)
79
+        return hop;
80
+
81
+    return -1;
82
+}
83
+
84
+
85
+int World::getAdjoiningRoom(int index,
86
+        float x, float y, float z,
87
+        float x2, float y2, float z2)
88
+{
89
+    room_mesh_t *room = mRooms[index];
90
+    portal_t * portal;
91
+    vec3_t intersect, p1, p2;
92
+
93
+
94
+    p1[0] = x;  p1[1] = y;  p1[2] = z;
95
+    p2[0] = x2; p2[1] = y2; p2[2] = z2;
96
+
97
+    if (room)
98
+    {
99
+        for(std::vector<int>::size_type i = 0; i != room->portals.size(); i++)
100
+        {
101
+            portal = room->portals[i];
102
+
103
+            if (!portal)
104
+                continue;
105
+
106
+            if (intersectionLinePolygon(intersect, p1, p2, // 4,
107
+                        portal->vertices))
108
+            {
109
+                return portal->adjoining_room;
110
+            }
111
+        }
112
+    }
113
+
114
+    return -1;
115
+}
116
+
117
+
118
+int World::getSector(int room, float x, float z, float *floor, float *ceiling)
119
+{
120
+    room_mesh_t *r;
121
+    sector_t * s;
122
+    int sector;
123
+
124
+
125
+    r = mRooms[room];
126
+
127
+    if (!r)
128
+        return -1;
129
+
130
+    sector = (((((int)x - (int)r->pos[0]) / 1024) * r->numZSectors) +
131
+            (((int)z - (int)r->pos[2]) / 1024));
132
+
133
+    if (sector > -1)
134
+    {
135
+        s = r->sectors[sector];
136
+
137
+        if (!s)
138
+            return -1;
139
+
140
+        *floor = s->floor;
141
+        *ceiling = s->ceiling;
142
+    }
143
+
144
+    return sector;
145
+}
146
+
147
+
148
+int World::getSector(int room, float x, float z)
149
+{
150
+    int sector;
151
+    room_mesh_t *r;
152
+
153
+
154
+    r = mRooms[room];
155
+
156
+    if (!r)
157
+    {
158
+        return -1;
159
+    }
160
+
161
+    sector = (((((int)x - (int)r->pos[0]) / 1024) * r->numZSectors) +
162
+            (((int)z - (int)r->pos[2]) / 1024));
163
+
164
+    if (sector < 0)
165
+    {
166
+        return -1;
167
+    }
168
+
169
+    return sector;
170
+}
171
+
172
+
173
+unsigned int World::getRoomInfo(int room)
174
+{
175
+    room_mesh_t *r;
176
+
177
+
178
+    r = mRooms[room];
179
+
180
+    if (!r)
181
+    {
182
+        return 0;
183
+    }
184
+
185
+    return r->flags;
186
+}
187
+
188
+
189
+bool World::isWall(int room, int sector)
190
+{
191
+    room_mesh_t *r;
192
+    sector_t *sect;
193
+
194
+
195
+    r = mRooms[room];
196
+
197
+    if (!r)
198
+    {
199
+        return true;
200
+    }
201
+
202
+    sect = r->sectors[sector];
203
+
204
+    if (!sect)
205
+    {
206
+        return true;
207
+    }
208
+
209
+    return (sector > 0 && sect->wall);
210
+}
211
+
212
+
213
+bool World::getHeightAtPosition(int index, float x, float *y, float z)
214
+{
215
+    room_mesh_t *room = mRooms[index];
216
+
217
+#ifdef OBSOLETE_USING_BOXES
218
+    unsigned int i;
219
+    float zmax, xmax, zmin, xmin;
220
+
221
+
222
+    if (!room)
223
+    {
224
+        return false;
225
+    }
226
+
227
+    // Mongoose 2002.08.14, It's 0302 - give me a fucking break --
228
+    //   this works albeit poorly  =)
229
+    for (i = 0; (int)i < room->num_boxes; ++i)
230
+    {
231
+        xmax = room->boxes[i].c.pos[0];
232
+        xmin = room->boxes[i].a.pos[0];
233
+        zmax = room->boxes[i].c.pos[2];
234
+        zmin = room->boxes[i].a.pos[2];
235
+
236
+        if (x < xmax && x > xmin && z < zmax && z > zmin)
237
+        {
238
+            //printf("%f %f %f %f\n", xmax, xmin, zmax, zmin);
239
+
240
+            *y =  room->boxes[i].a.pos[1]; // hhmm...room->pos[1] +
241
+            return true;
242
+        }
243
+    }
244
+
245
+    return false;
246
+#else
247
+    int sector;
248
+    sector_t *sect;
249
+
250
+
251
+    if (!room)
252
+    {
253
+        return false;
254
+    }
255
+
256
+    // Mongoose 2002.08.14, Remember sector_z is width of sector array
257
+    sector = getSector(index, x, z);
258
+
259
+    sect = room->sectors[sector];
260
+
261
+    if (!sect)
262
+    {
263
+        return true;
264
+    }
265
+
266
+    *y = sect->floor;
267
+
268
+    return true;
269
+#endif
270
+}
271
+
272
+
273
+// Temp methods for rendering use until more refactoring is done
274
+#ifdef BAD_BLOOD
275
+model_mesh_t *World::getMesh(int index)
276
+{
277
+    return mMeshes[index];
278
+}
279
+
280
+skeletal_model_t *World::getModel(int index)
281
+{
282
+    return mModels[index];
283
+}
284
+
285
+room_mesh_t *World::getRoom(int index)
286
+{
287
+    return mRooms[index];
288
+}
289
+
290
+std::vector<entity_t *> *World::getEntities()
291
+{
292
+    return &mEntities;
293
+}
294
+
295
+std::vector<sprite_seq_t *> *World::getSprites()
296
+{
297
+    return &mSprites;
298
+}
299
+
300
+std::vector<room_mesh_t *> *World::getRooms()
301
+{
302
+    return &mRooms;
303
+}
304
+#endif
305
+
306
+
307
+////////////////////////////////////////////////////////////
308
+// Public Mutators
309
+////////////////////////////////////////////////////////////
310
+
311
+void World::setFlag(WorldFlag flag)
312
+{
313
+    mFlags |= flag;
314
+}
315
+
316
+
317
+
318
+void World::clearFlag(WorldFlag flag)
319
+{
320
+    mFlags |= flag;
321
+    mFlags ^= flag;
322
+}
323
+
324
+
325
+void World::destroy()
326
+{
327
+    // Add some locking to check use state first
328
+    if (!mClearLock)
329
+    {
330
+        clear();
331
+    }
332
+}
333
+
334
+
335
+void World::addRoom(room_mesh_t *room)
336
+{
337
+    mClearLock = false;
338
+    mRooms.push_back(room);
339
+}
340
+
341
+
342
+void World::addMesh(model_mesh_t *mesh)
343
+{
344
+    if (mesh)
345
+    {
346
+        mClearLock = false;
347
+        mMeshes.push_back(mesh);
348
+    }
349
+}
350
+
351
+
352
+void World::addEntity(entity_t *e)
353
+{
354
+    if (e)
355
+    {
356
+        mClearLock = false;
357
+        e->master = 0x0;
358
+        e->moveType = worldMoveType_walk; // Walk
359
+        e->room = getRoomByLocation(e->pos[0], e->pos[1], e->pos[2]);
360
+        mEntities.push_back(e);
361
+    }
362
+}
363
+
364
+
365
+int World::addModel(skeletal_model_t *model)
366
+{
367
+    if (model)
368
+    {
369
+        mClearLock = false;
370
+        mModels.push_back(model);
371
+        return mModels.size() - 1;
372
+    }
373
+
374
+    return -1;
375
+}
376
+
377
+
378
+void World::addSprite(sprite_seq_t *sprite)
379
+{
380
+    if (sprite)
381
+    {
382
+        mClearLock = false;
383
+        mSprites.push_back(sprite);
384
+    }
385
+}
386
+
387
+
388
+void World::moveEntity(entity_t *e, char movement)
389
+{
390
+    const float moved = 180.0f;
391
+    const float testd = 220.0f;
392
+    const float camHeight = 8.0f;
393
+    float x, y, z, pitch, h, floor, ceiling;
394
+    int room, sector;
395
+    bool wall;
396
+    unsigned int roomFlags;
397
+
398
+
399
+    if (!e)
400
+    {
401
+        return;
402
+    }
403
+
404
+    switch (e->moveType)
405
+    {
406
+        case worldMoveType_walkNoSwim:
407
+        case worldMoveType_walk:
408
+            pitch = 0.0f;  // in the future pitch could control jump up blocks here
409
+            break;
410
+
411
+        case worldMoveType_noClipping:
412
+        case worldMoveType_fly:
413
+        case worldMoveType_swim:
414
+            pitch = e->angles[2];
415
+            break;
416
+    }
417
+
418
+    switch (movement)
419
+    {
420
+        case 'f':
421
+            x = e->pos[0] + (testd * sinf(e->angles[1]));
422
+            y = e->pos[1] + (testd * sinf(pitch));
423
+            z = e->pos[2] + (testd * cosf(e->angles[1]));
424
+            break;
425
+        case 'b':
426
+            x = e->pos[0] - (testd * sinf(e->angles[1]));
427
+            y = e->pos[1] - (testd * sinf(pitch));
428
+            z = e->pos[2] - (testd * cosf(e->angles[1]));
429
+            break;
430
+        case 'l':
431
+            x = e->pos[0] - (testd * sinf(e->angles[1] + 90.0f));
432
+            y = e->pos[1];
433
+            z = e->pos[2] - (testd * cosf(e->angles[1] + 90.0f));
434
+            break;
435
+        case 'r':
436
+            x = e->pos[0] + (testd * sinf(e->angles[1] + 90.0f));
437
+            y = e->pos[1];
438
+            z = e->pos[2] + (testd * cosf(e->angles[1] + 90.0f));
439
+            break;
440
+        default:
441
+            return;
442
+    }
443
+
444
+    //room = getRoomByLocation(x, y, z);
445
+    room = getRoomByLocation(e->room, x, y, z);
446
+
447
+    if (room == -1) // Will we hit a portal?
448
+    {
449
+#define ADJ_ROOM_CHECK
450
+#ifdef ADJ_ROOM_CHECK
451
+        room = getAdjoiningRoom(e->room,
452
+                e->pos[0],  e->pos[1], e->pos[2],
453
+                x, y, z);
454
+#else
455
+        if (!mFlags & fEnableHopping)
456
+        {
457
+            mFlags |= fEnableHopping;
458
+            room = getRoomByLocation(e->room, x, y, z);
459
+            printf("Hopped\n");
460
+            mFlags ^= fEnableHopping;
461
+        }
462
+
463
+        //room = getRoomByLocation(x, y, z);
464
+#endif
465
+
466
+        if (room > -1)
467
+        {
468
+            printf("Crossing from room %i to %i\n", e->room, room);
469
+        }
470
+    }
471
+
472
+    roomFlags = getRoomInfo(room);
473
+    sector = getSector(room, x, z, &floor, &ceiling);
474
+    wall = isWall(room, sector);
475
+
476
+    // If you're underwater you may want to swim  =)
477
+    // ...if you're worldMoveType_walkNoSwim, you better hope it's shallow
478
+    if (roomFlags & roomFlag_underWater && e->moveType == worldMoveType_walk)
479
+    {
480
+        e->moveType = worldMoveType_swim;
481
+    }
482
+
483
+    // Don't swim on land
484
+    if (!(roomFlags & roomFlag_underWater) && e->moveType == worldMoveType_swim)
485
+    {
486
+        e->moveType = worldMoveType_walk;
487
+    }
488
+
489
+    // Mongoose 2002.09.02, Add check for room -> room transition
490
+    //   ( Only allow by movement between rooms by using portals )
491
+    if (((e->moveType == worldMoveType_noClipping) ||
492
+                (e->moveType == worldMoveType_fly) ||
493
+                (e->moveType == worldMoveType_swim)) ||
494
+            ((room > -1) && (!wall)))
495
+    {
496
+        e->room = room;
497
+
498
+        switch (movement)
499
+        {
500
+            case 'f':
501
+                x = e->pos[0] + (moved * sinf(e->angles[1]));
502
+                y = e->pos[1] + (moved * sinf(pitch));
503
+                z = e->pos[2] + (moved * cosf(e->angles[1]));
504
+                break;
505
+            case 'b':
506
+                x = e->pos[0] - (moved * sinf(e->angles[1]));
507
+                y = e->pos[1] - (moved * sinf(pitch));
508
+                z = e->pos[2] - (moved * cosf(e->angles[1]));
509
+                break;
510
+            case 'l':
511
+                x = e->pos[0] - (moved * sinf(e->angles[1] + 90.0f));
512
+                z = e->pos[2] - (moved * cosf(e->angles[1] + 90.0f));
513
+                break;
514
+            case 'r':
515
+                x = e->pos[0] + (moved * sinf(e->angles[1] + 90.0f));
516
+                z = e->pos[2] + (moved * cosf(e->angles[1] + 90.0f));
517
+                break;
518
+        }
519
+
520
+        /*! \fixme Test for vector (move vector) / plane (portal) collision here
521
+         * to see if we need to switch rooms... man...
522
+         */
523
+
524
+        h = y;
525
+        getHeightAtPosition(room, x, &h, z);
526
+
527
+        switch (e->moveType)
528
+        {
529
+            case worldMoveType_fly:
530
+            case worldMoveType_swim:
531
+#ifdef DIVE_GAP
532
+                // Clips to top of water, waiting for DIVE event
533
+                if (h < floor)
534
+                    e->pos[1] = floor;
535
+                else if (h > ceiling)
536
+                    e->pos[1] = ceiling;
537
+                else
538
+                    e->pos[1] = y;
539
+#endif
540
+
541
+                // Don't fall out of world, avoid a movement that does
542
+                if (h > y - camHeight)
543
+                {
544
+                    e->pos[0] = x;
545
+                    e->pos[1] = y;
546
+                    e->pos[2] = z;
547
+                }
548
+                break;
549
+            case worldMoveType_walk:
550
+            case worldMoveType_walkNoSwim:
551
+                y = e->pos[1];  // Override vector movement walking ( er, not pretty )
552
+
553
+                // Now fake gravity
554
+                // Mongoose 2002.08.14, Remember TR is upside down ( you fall 'up' )
555
+
556
+                //ddist = h - e->pos[1];
557
+
558
+                // This is to force false gravity, by making camera stay on ground
559
+                e->pos[1] = h; //roomFloor->bbox_min[1];
560
+
561
+                // Check for camera below terrian and correct
562
+                if (e->pos[1] < h - camHeight)
563
+                {
564
+                    e->pos[1] = h - camHeight;
565
+                }
566
+
567
+                e->pos[0] = x;
568
+                e->pos[2] = z;
569
+                break;
570
+            case worldMoveType_noClipping:
571
+                e->pos[0] = x;
572
+                e->pos[1] = y;
573
+                e->pos[2] = z;
574
+        }
575
+
576
+#ifdef OBSOLETE
577
+        m_text->SetString(1,"Room %2i  Sector %2i %sPos %.0f %.0f %.0f Yaw %.0f",
578
+                room, sector,
579
+                wall ? " Wall " : " ",
580
+                e->pos[0], e->pos[1], e->pos[2], e->angles[1]);
581
+#endif
582
+    }
583
+    else
584
+    {
585
+        e->moving = false;
586
+        return;
587
+    }
588
+
589
+    e->room = room;
590
+    e->moving = true;
591
+}
592
+
593
+
594
+////////////////////////////////////////////////////////////
595
+// Private Accessors
596
+////////////////////////////////////////////////////////////
597
+
598
+
599
+////////////////////////////////////////////////////////////
600
+// Private Mutators
601
+////////////////////////////////////////////////////////////
602
+
603
+void World::clear()
604
+{
605
+    room_mesh_t *room;
606
+    model_mesh_t *mesh;
607
+    sprite_seq_t *sprite;
608
+    skeletal_model_t *model;
609
+    bone_frame_t *boneframe;
610
+    bone_tag_t *tag;
611
+    animation_frame_t *animation;
612
+    std::list<skeletal_model_t *> cache;
613
+
614
+    mClearLock = true;
615
+
616
+    for (std::vector<int>::size_type i = 0; i != mEntities.size(); i++)
617
+        delete mEntities[i];
618
+    mEntities.clear();
619
+
620
+    for (std::vector<int>::size_type i = 0; i != mRooms.size(); i++) {
621
+        room = mRooms[i];
622
+
623
+        if (room) {
624
+            for (std::vector<int>::size_type j = 0; j != room->portals.size(); j++)
625
+                delete room->portals[i];
626
+            room->portals.clear();
627
+
628
+            for (std::vector<int>::size_type j = 0; j != room->models.size(); j++)
629
+                delete room->models[i];
630
+            room->models.clear();
631
+
632
+            for (std::vector<int>::size_type j = 0; j != room->sprites.size(); j++)
633
+                delete room->sprites[i];
634
+            room->sprites.clear();
635
+
636
+            for (std::vector<int>::size_type j = 0; j != room->sectors.size(); j++)
637
+                delete room->sectors[i];
638
+            room->sectors.clear();
639
+
640
+            for (std::vector<int>::size_type j = 0; j != room->boxes.size(); j++)
641
+                delete room->boxes[i];
642
+            room->boxes.clear();
643
+
644
+            delete room;
645
+        }
646
+    }
647
+
648
+    for (std::vector<int>::size_type i = 0; i != mMeshes.size(); i++) {
649
+        mesh = mMeshes[i];
650
+
651
+        if (!mesh)
652
+            continue;
653
+
654
+        for (std::vector<int>::size_type j = 0; j != mesh->texturedTriangles.size(); j++)
655
+        {
656
+            if (mesh->texturedTriangles[j])
657
+                delete mesh->texturedTriangles[j];
658
+        }
659
+
660
+        for (std::vector<int>::size_type j = 0; j != mesh->coloredTriangles.size(); j++)
661
+        {
662
+            if (mesh->coloredTriangles[j])
663
+                delete mesh->coloredTriangles[j];
664
+        }
665
+
666
+        for (std::vector<int>::size_type j = 0; j != mesh->texturedRectangles.size(); j++)
667
+        {
668
+            if (mesh->texturedRectangles[j])
669
+                delete mesh->texturedRectangles[j];
670
+        }
671
+
672
+        for (std::vector<int>::size_type j = 0; j != mesh->coloredRectangles.size(); j++)
673
+        {
674
+            if (mesh->coloredRectangles[j])
675
+                delete mesh->coloredRectangles[j];
676
+        }
677
+
678
+        if (mesh->vertices)
679
+            delete [] mesh->vertices;
680
+
681
+        if (mesh->colors)
682
+            delete [] mesh->colors;
683
+
684
+        if (mesh->normals)
685
+            delete [] mesh->normals;
686
+
687
+        delete mesh;
688
+    }
689
+
690
+    mMeshes.clear();
691
+
692
+    for (std::vector<int>::size_type i = 0; i != mSprites.size(); i++)
693
+    {
694
+        sprite = mSprites[i];
695
+
696
+        if (!sprite)
697
+            continue;
698
+
699
+        if (sprite->sprite)
700
+            delete [] sprite->sprite;
701
+
702
+        delete sprite;
703
+    }
704
+
705
+    mSprites.clear();
706
+
707
+    for (std::vector<int>::size_type i = 0; i != mModels.size(); i++)
708
+    {
709
+        model = mModels[i];
710
+
711
+        if (!model)
712
+            continue;
713
+
714
+        // No smart pointers, so skip if deleted once  =)
715
+        bool found = false;
716
+        for (std::list<skeletal_model_t *>::const_iterator iterator = cache.begin(), end = cache.end(); iterator != end; ++iterator) {
717
+            if (model == *iterator) {
718
+                found = true;
719
+                break;
720
+            }
721
+        }
722
+
723
+        if (!found)
724
+        {
725
+            cache.push_back(model);
726
+        }
727
+        else
728
+        {
729
+            continue;
730
+        }
731
+
732
+        for (std::vector<int>::size_type j = 0; j != model->animation.size(); j++)
733
+        {
734
+            animation  = model->animation[j];
735
+
736
+            if (!animation)
737
+                continue;
738
+
739
+            for (std::vector<int>::size_type k = 0; k != animation->frame.size(); k++)
740
+            {
741
+                boneframe = animation->frame[k];
742
+
743
+                if (!boneframe)
744
+                    continue;
745
+
746
+                for (std::vector<int>::size_type l = 0; l != boneframe->tag.size(); l++)
747
+                {
748
+                    tag = boneframe->tag[l];
749
+
750
+                    if (!tag)
751
+                        continue;
752
+
753
+                    delete tag;
754
+                }
755
+
756
+                delete boneframe;
757
+            }
758
+
759
+            delete animation;
760
+        }
761
+
762
+        delete model;
763
+    }
764
+
765
+    mModels.clear();
766
+}
767
+

Загрузка…
Отмена
Сохранить