forked from NikitaNikson/X-Ray_Renewal_Engine
-
Notifications
You must be signed in to change notification settings - Fork 1
/
xr_collide_defs.h
139 lines (133 loc) · 3.63 KB
/
xr_collide_defs.h
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
#pragma once
#include "xrcdb.h"
class CObject;
namespace collide
{
struct tri {
Fvector e10; float e10s;
Fvector e21; float e21s;
Fvector e02; float e02s;
Fvector p[3];
Fvector N;
float d;
};
struct elipsoid {
Fmatrix mL2W; // convertion from sphere(000,1) to real space
Fmatrix mW2L; // convertion from real space to sphere(000,1)
};
struct ray_cache
{
// previous state
Fvector start;
Fvector dir;
float range;
BOOL result;
// cached vertices
Fvector verts[3];
ray_cache()
{
start.set (0,0,0);
dir.set (0,0,0);
range = 0;
result = FALSE;
verts[0].set(0,0,0);
verts[1].set(0,0,0);
verts[2].set(0,0,0);
}
void set (const Fvector& _start, const Fvector& _dir, const float _range,const BOOL _result)
{
start = _start;
dir = _dir;
range = _range;
result = _result;
}
BOOL similar (const Fvector& _start, const Fvector& _dir, const float _range)
{
if (!_start.similar(start)) return FALSE;
if (!fsimilar(1.f,dir.dotproduct(_dir))) return FALSE;
if (!fsimilar(_range,range)) return FALSE;
return TRUE;
}
};
enum rq_target {
rqtNone = (0),
rqtObject = (1<<0),
rqtStatic = (1<<1),
rqtShape = (1<<2),
rqtObstacle = (1<<3),
rqtBoth = (rqtObject|rqtStatic),
rqtDyn = (rqtObject|rqtShape|rqtObstacle)
};
struct ray_defs
{
Fvector start;
Fvector dir;
float range;
u32 flags;
rq_target tgt;
ray_defs (const Fvector& _start, const Fvector& _dir, float _range, u32 _flags, rq_target _tgt)
{
start = _start;
dir = _dir;
range = _range;
flags = _flags;
tgt = _tgt;
}
};
struct rq_result
{
CObject* O; // if NULL - static
float range; // range to intersection
int element; // номер кости/номер треугольника
IC rq_result& set (CObject* _O, float _range, int _element)
{
O = _O;
range = _range;
element = _element;
return *this;
}
IC BOOL set_if_less (CDB::RESULT* I){if (I->range<range){ set(0,I->range,I->id); return TRUE;}else return FALSE;}
IC BOOL set_if_less (rq_result* R){if (R->range<range){ set(R->O,R->range,R->element); return TRUE;}else return FALSE;}
IC BOOL set_if_less (CObject* _who, float _range, int _element) { if (_range<range) { set(_who,_range,_element); return TRUE;}else return FALSE;}
IC BOOL valid () {return (element>=0);}
};
DEFINE_VECTOR (rq_result,rqVec,rqIt);
class rq_results
{
protected:
rqVec results;
static bool r_sort_pred (const rq_result& a, const rq_result& b) { return a.range<b.range;}
public:
IC BOOL append_result (CObject* _who, float _range, int _element, BOOL bNearest)
{
if (bNearest&&!results.empty()){
rq_result& R = results.back();
if (_range<R.range){
R.O =_who;
R.range =_range;
R.element =_element;
return TRUE;
}
return FALSE;
}
auto& rq = results.emplace_back();
rq.range =_range;
rq.element =_element;
rq.O =_who;
return TRUE ;
}
IC void append_result (rq_result& res)
{
if (0==results.capacity()) results.reserve(8);
results.push_back (res);
}
IC int r_count () { return results.size(); }
IC rq_result* r_begin() { return std::data(results); }
IC rq_result* r_end() { return std::data(results) + std::size(results); }
IC void r_clear () { results.clear_not_free(); }
IC void r_sort () { std::sort(results.begin(),results.end(),r_sort_pred);}
IC rqVec &r_results () { return results; }
};
typedef BOOL rq_callback (rq_result& result, LPVOID user_data);
typedef BOOL test_callback (const ray_defs& rd, CObject* object, LPVOID user_data);
};