/
worldtri.hpp
148 lines (115 loc) · 3.87 KB
/
worldtri.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/******************************************************************************
BigWorld Technology
Copyright BigWorld Pty, Ltd.
All Rights Reserved. Commercial in confidence.
WARNING: This computer program is protected by copyright law and international
treaties. Unauthorized use, reproduction or distribution of this program, or
any portion of this program, may result in the imposition of civil and
criminal penalties as provided by law.
******************************************************************************/
/**
* @file
*/
#ifndef WORLDTRIANGLE_HPP
#define WORLDTRIANGLE_HPP
#include <vector>
#include "cstdmf/stdmf.hpp"
#include "math/vector2.hpp"
#include "math/vector3.hpp"
#include "math/planeeq.hpp"
// Enable this to see debug lines for intersection tests.
//#define BW_WORLDTRIANGLE_DEBUG
#ifdef BW_WORLDTRIANGLE_DEBUG
#include "math/matrix.hpp"
#endif
enum
{
// Nothing will ever collide with this triangle
TRIANGLE_NOT_IN_BSP = 0xff,
TRIANGLE_CAMERANOCOLLIDE = 1 << 0,
TRIANGLE_TRANSPARENT = 1 << 1,
TRIANGLE_BLENDED = 1 << 2,
TRIANGLE_TERRAIN = 1 << 3,
// Player does not collide. Camera still does
TRIANGLE_NOCOLLIDE = 1 << 4,
TRIANGLE_DOUBLESIDED = 1 << 5,
TRIANGLE_DOOR = 1 << 6,
TRIANGLE_UNUSED_7 = 1 << 7,
TRIANGLE_COLLISIONFLAG_MASK = 0xff,
TRIANGLE_MATERIALKIND_MASK = 0xff << 8,
TRIANGLE_MATERIALKIND_SHIFT = 8 // how many bits to shift to get to the byte we want
};
/**
* This class is used to represent a triangle in the collision scene.
*/
class WorldTriangle
{
public:
typedef uint16 Flags;
typedef uint16 Padding;
// construction
WorldTriangle( const Vector3 & v0,
const Vector3 & v1,
const Vector3 & v2,
Flags flags = 0 );
WorldTriangle();
// tests
bool intersects( const WorldTriangle & triangle ) const;
bool intersects( const Vector3 & start,
const Vector3 & dir,
float & dist ) const;
bool intersects( const WorldTriangle & triangle,
const Vector3 & offset ) const;
// utility
Vector2 project( const Vector3 & onTri ) const;
const Vector3 & v0() const;
const Vector3 & v1() const;
const Vector3 & v2() const;
const Vector3 & v( uint32 index ) const;
Vector3 normal() const;
void bounce(Vector3 & v,
float elasticity = 1.f) const;
// flags
static Flags packFlags( int collisionFlags, int materialKind );
static int collisionFlags( Flags flags )
{ return (flags & TRIANGLE_COLLISIONFLAG_MASK); }
static int materialKind( Flags flags )
{ return (flags & TRIANGLE_MATERIALKIND_MASK) >> TRIANGLE_MATERIALKIND_SHIFT; }
Flags flags() const;
void flags( Flags newFlags );
bool isTransparent() const;
bool isBlended() const;
uint collisionFlags() const { return collisionFlags( flags_ ); }
uint materialKind() const { return materialKind( flags_ ); }
bool operator==(const WorldTriangle& rhs) const
{
return v_[0] == rhs.v_[0] && v_[1] == rhs.v_[1] && v_[2] == rhs.v_[2]
&& flags_ == rhs.flags_ && padding_ == rhs.padding_;
}
#ifdef BW_WORLDTRIANGLE_DEBUG
static void BeginDraw( const Matrix& transform, uint32 lifeTime = 0,
uint32 hitFailureTime = 0 );
static void EndDraw();
private:
// Enable to draw debug triangles in collision tests. If you do you must also
// set transform to correct mapping from chunk to world space.
static bool s_debugTriangleDraw_;
static Matrix s_debugTriangleTransform_;
// If the debug triangles are drawn every frame, then life = 0 (the default).
// Otherwise set this to indicate how many frames to draw them.
static uint32 s_debugTriangleLife_;
// How long to draw the failure for a hit test
static uint32 s_debugHitTestFailureLife_;
#endif
private:
Vector3 v_[3];
Flags flags_;
Padding padding_;
};
/// This type stores a collection of triangles.
typedef std::vector<const WorldTriangle *> WTriangleSet;
typedef std::vector<WorldTriangle> RealWTriangleSet;
#ifdef CODE_INLINE
#include "worldtri.ipp"
#endif
#endif // WORLDTRIANGLE_HPP