-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgravity_particle.cpp
More file actions
119 lines (94 loc) · 2.86 KB
/
gravity_particle.cpp
File metadata and controls
119 lines (94 loc) · 2.86 KB
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
#include "gravity_actor_extension.h"
using namespace Particle;
Matrix4x3 particleViewMatrix;
extern Actor* behavingActor;
static void CalculateFieldMatrix(Matrix3x3& res, Vector3_Q24 upAxis)
{
SphericalMatrixField (
res,
static_cast<Vector3_Q24>(INV_VIEW_MATRIX_ASR_3.c0),
static_cast<Vector3_Q24>(INV_VIEW_MATRIX_ASR_3.c2),
upAxis
);
}
static void RotateAroundActor(Vector3& posAsr3, const Actor& actor, const ActorExtension& extension)
{
posAsr3.RotateAround(actor.pos >> 3, extension.GetGravityMatrix());
}
asm(R"(
repl_02022f04:
ldr r1, =particleViewMatrix
bx lr
nsub_02049f34:
mov r0, r5
bl SetParticleViewMatrix
mov r0, r4
b 0x02049f38
)");
extern "C" void SetParticleViewMatrix(const System& system)
{
const Vector3 pos = system.posAsr3 << 3;
const GravityField& field = GravityField::GetFieldAt(pos);
if (field.IsTrivial())
{
particleViewMatrix = VIEW_MATRIX_ASR_3;
return;
}
CalculateFieldMatrix(particleViewMatrix.Linear(), field.GetUpVectorQ24(pos));
particleViewMatrix.c3 = system.posAsr3 - particleViewMatrix.Linear()(system.posAsr3);
particleViewMatrix = VIEW_MATRIX_ASR_3(particleViewMatrix);
}
asm(R"(
nsub_0204ae2c:
ldr r3, =behavingActor
ldr r3, [r3]
cmp r3, #0
bne TransformSystemPos
ContinueTo0204ae30:
push {r14}
b 0x0204ae30
)");
extern "C" void ContinueTo0204ae30(System& system, SysDef* sysDef, const Vector3& posAsr3);
extern "C" void TransformSystemPos(System& system, SysDef* sysDef, const Vector3& posAsr3, const Actor& actor)
{
const ActorExtension& extension = ActorExtension::Get(actor);
if (extension.IsInTrivialField())
return ContinueTo0204ae30(system, sysDef, posAsr3);
Vector3 newPos = posAsr3;
RotateAroundActor(newPos, actor, extension);
return ContinueTo0204ae30(system, sysDef, newPos);
}
asm(R"(
nsub_02022dd8:
ldr r0, [r5, #0xc]
add r1, r13, #4
bl TransformParticles
mov r1, r0
b 0x02022ddc
)");
extern "C" System& TransformParticles(System& system, Vector3& newPosAsr3)
{
const GravityField* field;
if (behavingActor)
{
const ActorExtension& extension = ActorExtension::Get(*behavingActor);
if (extension.IsInTrivialField()) return system;
field = &extension.GetGravityField();
RotateAroundActor(newPosAsr3, *behavingActor, extension);
}
else
{
field = &GravityField::GetFieldAt(newPosAsr3 << 3);
if (field->IsTrivial()) return system;
}
Matrix4x3 transform0, transform1;
CalculateFieldMatrix(transform0.Linear(), field->GetUpVectorQ24(system.posAsr3 << 3));
CalculateFieldMatrix(transform1.Linear(), field->GetUpVectorQ24(newPosAsr3 << 3));
transform0.c3 = system.posAsr3 - newPosAsr3 - transform0.Linear()(system.posAsr3);
transform1.Linear().TransposeInPlace();
transform1.c3 = newPosAsr3;
transform1 = transform1(transform0);
for (auto& particle : system.particleList)
particle.posAsr3 *= transform1;
return system;
}