Isle
Loading...
Searching...
No Matches
legopathboundary.cpp
Go to the documentation of this file.
1#include "legopathboundary.h"
2
3#include "decomp.h"
6#include "legopathactor.h"
7#include "legopathstruct.h"
8
10
11// FUNCTION: LEGO1 0x10056a70
12// FUNCTION: BETA10 0x100b1360
14{
15}
16
17// FUNCTION: LEGO1 0x10057260
18// FUNCTION: BETA10 0x100b140d
20{
21 for (LegoPathActorSet::iterator it = m_actors.begin(); !(it == m_actors.end()); it++) {
22 (*it)->SetBoundary(NULL);
23 }
24
25 m_actors.erase(m_actors.begin(), m_actors.end());
26}
27
28// FUNCTION: LEGO1 0x100573f0
29// FUNCTION: BETA10 0x100b1536
31{
32 m_actors.insert(p_actor);
33 p_actor->SetBoundary(this);
34 return SUCCESS;
35}
36
37// FUNCTION: LEGO1 0x100574a0
38// FUNCTION: BETA10 0x100b156f
40{
41 m_actors.erase(p_actor);
42 return SUCCESS;
43}
44
45// FUNCTION: LEGO1 0x100575b0
46// FUNCTION: BETA10 0x100b1598
47void LegoPathBoundary::FUN_100575b0(Vector3& p_point1, Vector3& p_point2, LegoPathActor* p_actor)
48{
49 Vector3* ccwV = NULL;
50
51 if (m_numTriggers > 0 && m_unk0x50 != NULL) {
52 ccwV = m_edges[0]->CCWVertex(*this);
54
55 v = p_point1;
56 v -= *ccwV;
57 float dot1 = v.Dot(v, *m_unk0x50);
58
59 v = p_point2;
60 v -= *ccwV;
61 float dot2 = v.Dot(v, *m_unk0x50);
62
63 if (dot2 > dot1) {
64 for (MxS32 i = 0; i < m_numTriggers; i++) {
66
67 if (m_pathTrigger[i].m_unk0x08 >= dot1 && m_pathTrigger[i].m_unk0x08 < dot2) {
68 s->HandleTrigger(p_actor, TRUE, m_pathTrigger[i].m_data);
69 }
70 }
71 }
72 else if (dot2 < dot1) {
73 for (MxS32 i = 0; i < m_numTriggers; i++) {
75
76 if (m_pathTrigger[i].m_unk0x08 >= dot2 && m_pathTrigger[i].m_unk0x08 < dot1) {
77 s->HandleTrigger(p_actor, FALSE, m_pathTrigger[i].m_data);
78 }
79 }
80 }
81 }
82}
83
84// FUNCTION: LEGO1 0x10057720
85// FUNCTION: BETA10 0x100b17ef
87 LegoPathActor* p_actor,
88 LegoPathBoundary*& p_boundary,
89 LegoUnknown100db7f4*& p_edge,
90 float& p_unk0xe4
91)
92{
93 LegoUnknown100db7f4* e = p_edge;
94
95 if (p_edge->BETA_100b53b0(*p_boundary)) {
96 LegoPathBoundary* newBoundary = (LegoPathBoundary*) p_edge->OtherFace(p_boundary);
97
98 if (newBoundary == NULL) {
99 newBoundary = p_boundary;
100 }
101
102 MxS32 local10 = 0;
103 MxU8 userNavFlag;
104
105 if (e->BETA_1004a830(*newBoundary, 1)) {
106 userNavFlag = p_actor->GetUserNavFlag();
107 }
108 else {
109 userNavFlag = TRUE;
110 }
111
112 do {
113 p_edge = (LegoUnknown100db7f4*) p_edge->GetCounterclockwiseEdge(*newBoundary);
114 LegoPathBoundary* local20 = (LegoPathBoundary*) p_edge->OtherFace(newBoundary);
115
116 if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*local20, 1))) {
117 local10++;
118 }
119 } while (p_edge != e);
120
121 MxBool localc = TRUE;
122 MxS32 local8 = local10 - 1;
123
124 if (local10 <= 1) {
125 local8 = 0;
126 }
127 else if (local10 == 2) {
128 local8 = 1;
129 }
130 else {
131 p_actor->VTable0xa4(localc, local8);
132 }
133
134 while (local8 > 0) {
135 if (localc) {
136 p_edge = (LegoUnknown100db7f4*) p_edge->GetCounterclockwiseEdge(*newBoundary);
137 }
138 else {
139 p_edge = (LegoUnknown100db7f4*) p_edge->GetClockwiseEdge(*newBoundary);
140 }
141
142 LegoPathBoundary* local20 = (LegoPathBoundary*) p_edge->OtherFace(newBoundary);
143
144 if (p_edge->GetMask0x03() && (userNavFlag || p_edge->BETA_1004a830(*local20, 1))) {
145 local8--;
146 }
147 }
148
149 if (p_edge == e) {
150 p_edge = (LegoUnknown100db7f4*) p_edge->GetCounterclockwiseEdge(*newBoundary);
151 p_edge = (LegoUnknown100db7f4*) p_edge->GetCounterclockwiseEdge(*newBoundary);
152 }
153
154 if (p_boundary != newBoundary) {
155 p_boundary->RemoveActor(p_actor);
156 p_boundary = newBoundary;
157 p_boundary->AddActor(p_actor);
158 }
159 else {
160 p_unk0xe4 = 1.0 - p_unk0xe4;
161 }
162 }
163 else {
164 do {
165 p_edge = (LegoUnknown100db7f4*) p_edge->GetCounterclockwiseEdge(*p_boundary);
166
167 if (p_edge->GetMask0x03()) {
168 break;
169 }
170 } while (p_edge != e);
171
172 if (p_edge == e) {
173 p_edge = (LegoUnknown100db7f4*) p_edge->GetCounterclockwiseEdge(*p_boundary);
174 p_edge = (LegoUnknown100db7f4*) p_edge->GetCounterclockwiseEdge(*p_boundary);
175 }
176
177 p_unk0xe4 = 1.0 - p_unk0xe4;
178 }
179}
180
181// FUNCTION: LEGO1 0x10057950
182// FUNCTION: BETA10 0x100b1adc
184 float p_scale,
185 Vector3& p_point1,
186 Vector3& p_point2,
187 Vector3& p_point3,
188 LegoUnknown100db7f4*& p_edge
189)
190{
192 float localc;
193 MxU32 local10 = 0;
194 float len = 0.0f;
195 Mx3DPointFloat vec;
196
197 for (MxS32 i = 0; i < m_numEdges; i++) {
199
200 if (p_point2.Dot(m_edgeNormals[i], p_point2) + m_edgeNormals[i][3] <= -1e-07) {
201 if (local10 == 0) {
202 local10 = 1;
203 vec = p_point2;
204 vec -= p_point1;
205
206 len = vec.LenSquared();
207 if (len <= 0.0f) {
208 return 0;
209 }
210
211 len = sqrt(len);
212 vec /= len;
213 }
214
215 float dot = vec.Dot(vec, m_edgeNormals[i]);
216 if (dot != 0.0f) {
217 float local34 = (-m_edgeNormals[i][3] - p_point1.Dot(p_point1, m_edgeNormals[i])) / dot;
218
219 if (local34 >= -0.001 && local34 <= len && (e == NULL || local34 < localc)) {
220 e = edge;
221 localc = local34;
222 }
223 }
224 }
225 }
226
227 if (e != NULL) {
228 if (localc < 0.0f) {
229 localc = 0.0f;
230 }
231
232 Mx3DPointFloat local50;
233 Mx3DPointFloat local70;
234 Vector3* local5c = e->CWVertex(*this);
235
236 p_point3 = vec;
237 p_point3 *= localc;
238 p_point3 += p_point1;
239
240 local50 = p_point2;
241 local50 -= *local5c;
242
243 e->FUN_1002ddc0(*this, local70);
244
245 float local58 = local50.Dot(local50, local70);
246 LegoUnknown100db7f4* local54 = NULL;
247
248 if (local58 < 0.0f) {
249 Mx3DPointFloat local84;
250
251 for (LegoUnknown100db7f4* local88 = (LegoUnknown100db7f4*) e->GetClockwiseEdge(*this); e != local88;
252 local88 = (LegoUnknown100db7f4*) local88->GetClockwiseEdge(*this)) {
253 local88->FUN_1002ddc0(*this, local84);
254
255 if (local84.Dot(local84, local70) <= 0.9) {
256 break;
257 }
258
259 Vector3* local90 = local88->CWVertex(*this);
260 Mx3DPointFloat locala4(p_point3);
261 locala4 -= *local90;
262
263 float local8c = locala4.Dot(locala4, local84);
264
265 if (local8c > local58 && local8c < local88->m_unk0x3c) {
266 local54 = local88;
267 local58 = local8c;
268 local70 = local84;
269 local5c = local90;
270 }
271 }
272 }
273 else {
274 if (e->m_unk0x3c < local58) {
275 Mx3DPointFloat localbc;
276
278 e != locala8;
279 locala8 = (LegoUnknown100db7f4*) locala8->GetCounterclockwiseEdge(*this)) {
280 locala8->FUN_1002ddc0(*this, localbc);
281
282 if (localbc.Dot(localbc, local70) <= 0.9) {
283 break;
284 }
285
286 Vector3* localc4 = locala8->CWVertex(*this);
287 Mx3DPointFloat locald8(p_point3);
288 locald8 -= *localc4;
289
290 float localc0 = locald8.Dot(locald8, localbc);
291
292 if (localc0 < local58 && localc0 >= 0.0f) {
293 local54 = locala8;
294 local58 = localc0;
295 local70 = localbc;
296 local5c = localc4;
297 }
298 }
299 }
300 }
301
302 if (local54 != NULL) {
303 e = local54;
304 }
305
306 if (local58 <= 0.0f) {
307 if (!e->GetMask0x03()) {
308 p_edge = (LegoUnknown100db7f4*) e->GetClockwiseEdge(*this);
309 }
310 else {
311 p_edge = e;
312 }
313
314 p_point3 = *local5c;
315 return 2;
316 }
317 else if (local58 > 0.0f && e->m_unk0x3c > local58) {
318 p_point3 = local70;
319 p_point3 *= local58;
320 p_point3 += *local5c;
321 p_edge = e;
322 return 1;
323 }
324 else {
325 p_point3 = *e->CCWVertex(*this);
326
327 if (!e->GetMask0x03()) {
328 p_edge = (LegoUnknown100db7f4*) e->GetCounterclockwiseEdge(*this);
329 }
330 else {
331 p_edge = e;
332 }
333
334 return 2;
335 }
336 }
337
338 return 0;
339}
340
341// FUNCTION: LEGO1 0x10057fe0
342// FUNCTION: BETA10 0x100b2220
344{
345 Mx3DPointFloat unk0x30;
346
347 unk0x30 = m_unk0x30;
348 unk0x30 -= p_presenter->m_unk0xa8;
349
350 float len = unk0x30.LenSquared();
351 float local20 = p_presenter->m_unk0xa4 + m_unk0x44;
352
353 if (len > 0.001 && len > local20 * local20) {
354 return 0;
355 }
356
357 // TODO: This only seems to match if the type is not the same as the type of the
358 // key value of the set. Figure out which type the set (or parameter) actually uses.
359 // Also see call to .find in LegoPathController::FUN_10046050
360 m_presenters.insert(static_cast<LegoLocomotionAnimPresenter*>(p_presenter));
361 return 1;
362}
363
364// FUNCTION: LEGO1 0x100586e0
365// FUNCTION: BETA10 0x100b22d1
367{
368 if (p_presenter != NULL) {
369 // TODO: This only seems to match if the type is not the same as the type of the
370 // key value of the set. Figure out which type the set (or parameter) actually uses.
371 // Also see call to .find in LegoPathController::FUN_10046050
372 if (m_presenters.find(static_cast<LegoLocomotionAnimPresenter*>(p_presenter)) != m_presenters.end()) {
373 m_presenters.erase(static_cast<LegoLocomotionAnimPresenter*>(p_presenter));
374 return 1;
375 }
376 }
377 else {
378 for (LegoAnimPresenterSet::iterator it = m_presenters.begin(); it != m_presenters.end(); it++) {
379 (*it)->SetCurrentWorld(NULL);
380 }
381 }
382
383 return 0;
384}
[AI] Handles playback and synchronization of animated LEGO objects, including variable substitution,...
Mx3DPointFloat m_unk0xa8
[AI] 3D float property, used for animation base position offset.
float m_unk0xa4
[AI] Animation touch radius for path boundary checks and state (set from resource).
[AI] Specialized presenter class for handling locomotion animation playback and state in the LEGO Isl...
[AI] An actor that moves along a predefined path, supporting boundary transitions,...
Definition: legopathactor.h:32
void SetBoundary(LegoPathBoundary *p_boundary)
[AI] Assigns a new boundary for the actor (for path switching).
virtual MxBool GetUserNavFlag()
[AI] Returns user navigation state (whether actor follows player input).
virtual void VTable0xa4(MxBool &p_und1, MxS32 &p_und2)
[AI] Returns information depending on actor type.
[AI] Represents a path segment or boundary in the navigation network for actors (vehicles,...
void FUN_100575b0(Vector3 &p_point1, Vector3 &p_point2, LegoPathActor *p_actor)
[AI] Handles processing path triggers along this boundary as an actor moves from p_point1 to p_point2...
~LegoPathBoundary() override
[AI] Destructor.
MxU32 FUN_10057fe0(LegoAnimPresenter *p_presenter)
[AI] Adds an animation presenter to the set if within region, based on spatial bounds.
MxResult AddActor(LegoPathActor *p_actor)
[AI] Adds the given actor to this path boundary and sets its boundary pointer.
MxResult RemoveActor(LegoPathActor *p_actor)
[AI] Removes the actor from this boundary's actor set.
MxU32 FUN_100586e0(LegoAnimPresenter *p_presenter)
[AI] Removes an animation presenter from the set, or if nullptr resets all presenters' world associat...
void SwitchBoundary(LegoPathActor *p_actor, LegoPathBoundary *&p_boundary, LegoUnknown100db7f4 *&p_edge, float &p_unk0xe4)
[AI] Switches the boundary that the actor is associated with based on edge traversal.
MxU32 Intersect(float p_scale, Vector3 &p_point1, Vector3 &p_point2, Vector3 &p_point3, LegoUnknown100db7f4 *&p_edge)
[AI] Tests for intersection between a path and this boundary; finds the first edge hit and intersecti...
[AI] Represents a trigger/control element in the LEGO world's path system, linked logically to the wo...
virtual void HandleTrigger(LegoPathActor *p_actor, MxBool p_direction, MxU32 p_data)
[AI] Main trigger handler; evaluates flags and name-based script to decide what action to take when a...
LegoU8 m_numEdges
[AI] Number of edge elements in m_edges; number of sides of the polygon. [AI]
Definition: legoweedge.h:74
LegoUnknown100db7f4 ** m_edges
[AI] Array of pointers to edge objects (LegoUnknown100db7f4) comprising this face....
Definition: legoweedge.h:75
float m_unk0x44
[AI] Maximum squared distance from center—polygon bounding radius or similar. [AI]
Definition: legowegedge.h:115
LegoU8 m_numTriggers
[AI] Number of trigger (path/segment) structures attached to this edge. [AI]
Definition: legowegedge.h:116
Mx3DPointFloat * m_unk0x50
[AI] Transition direction/unit vector—used for edge trigger geometry. [AI]
Definition: legowegedge.h:118
Mx4DPointFloat * m_edgeNormals
[AI] Per-edge normals for each polygon segment, allocated dynamically. [AI]
Definition: legowegedge.h:113
PathWithTrigger * m_pathTrigger
[AI] Array of triggers influencing entity motion or event logic on this edge. [AI]
Definition: legowegedge.h:117
Mx3DPointFloat m_unk0x30
[AI] Cached center for the edge polygon, used in geometric calculations. [AI]
Definition: legowegedge.h:114
[AI] Represents a 3D point with floating-point precision, inheriting from Vector3.
Definition: mxgeometry3d.h:14
virtual float Dot(const float *p_a, const float *p_b) const
[AI] Compute the dot product of the two float arrays interpreted as vectors of 2 elements.
[AI] 3D vector class, providing vector and cross-product operations in 3D space.
Definition: vector.h:249
float LenSquared() const override
[AI] Computes the squared magnitude (x^2 + y^2 + z^2) of this vector.
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
Definition: legotypes.h:30
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
MxLong MxResult
[AI]
Definition: mxtypes.h:106
unsigned char MxU8
[AI]
Definition: mxtypes.h:8
signed int MxS32
[AI]
Definition: mxtypes.h:38
unsigned int MxU32
[AI]
Definition: mxtypes.h:32
Vector3 * CWVertex(LegoWEEdge &p_face)
[AI] Returns the "clockwise" endpoint of this edge with respect to a given face.
Definition: legoedge.cpp:56
LegoEdge * GetCounterclockwiseEdge(LegoWEEdge &p_face)
[AI] Returns the counterclockwise adjacent edge relative to the given face.
Definition: legoedge.cpp:41
LegoEdge * GetClockwiseEdge(LegoWEEdge &p_face)
[AI] Returns the clockwise adjacent edge relative to the given face.
Definition: legoedge.cpp:27
Vector3 * CCWVertex(LegoWEEdge &p_face)
[AI] Returns the "counterclockwise" endpoint of this edge with respect to a given face.
Definition: legoedge.cpp:69
[AI] Represents an advanced edge in the LEGO Island geometry system, with direction,...
LegoU32 GetMask0x03()
[AI] Returns a mask of flags relevant to the two faces (bits 0 and 1: c_bit1, c_bit2).
float m_unk0x3c
[AI] Unknown float; likely represents additional metric (possibly precomputed distance/weight).
LegoU32 BETA_1004a830(LegoWEGEdge &p_face, LegoU8 p_mask)
[AI] Tests whether a WEG-edge meets complex mask and flag criteria for this edge, depending on mask a...
LegoWEEdge * OtherFace(LegoWEEdge *p_other)
[AI] Returns the opposite face pointer to the one passed in.
LegoU32 BETA_100b53b0(LegoWEGEdge &p_face)
[AI] Checks if a WEG-edge is connected to this edge with proper flagging for its side.
LegoResult FUN_1002ddc0(LegoWEEdge &p_f, Vector3 &p_point) const
[AI] Calculates the edge normal for use from the given face, negating it if called from faceA.
LegoPathStruct * m_pathStruct
[AI] Pointer to a path structure associated with this trigger. [AI]
Definition: legowegedge.h:18