1#include "Game/Gravity.hpp"
2#include "Game/Util/MathUtil.hpp"
3#include "JSystem/JMath/JMath.hpp"
6bool TVec3f::isZero()
const {
7 register const TVec3f *rSrc =
this;
11 psq_l f1, 0(rSrc), 0, 0
14 ps_madd sum, sum, sum, f1
15 ps_sum0 sum, sum, f1, f1
18 return sum <= 0.0000038146973f;
22float TVec3f::normalize(
const TVec3f& rSrc) {
26 float magnitude = PSVECMag(toCVec());
27 PSVECNormalize(toCVec(), toVec());
42void CubeGravity::setCube(
const TPos3f & cube) {
48void CubeGravity::updateMtx(
const TPos3f &rMtx) {
49 mPosition.concat(rMtx, mCube);
51 mPosition.getXDir(dir);
52 lenX = VECMag(dir.toCVec());
53 mPosition.getYDir(dir);
54 lenY = VECMag(dir.toCVec());
55 mPosition.getZDir(dir);
56 lenZ = VECMag(dir.toCVec());
59bool CubeGravity::calcOwnGravityVector(TVec3f *pDest, f32 *pScalar,
const TVec3f &rPosition)
const {
60 int area = calcGravityArea(rPosition);
61 if(area < 0)
return false;
65 !calcFaceGravity(rPosition, area, &gravityForce, &scalar)
66 && !calcCornerGravity(rPosition, area, &gravityForce, &scalar)
67 && !calcEdgeGravity(rPosition, area, &gravityForce, &scalar)
70 if(isInRangeDistance(scalar))
return false;
73 *pDest = gravityForce;
80int CubeGravity::calcGravityArea(
const TVec3f &rPosition)
const {
81 TVec3f dirX, dirY, dirZ, trans;
82 mPosition.getXDir(dirX);
83 mPosition.getYDir(dirY);
84 mPosition.getZDir(dirZ);
85 mPosition.getTrans(trans);
86 TVec3f relativePosition = rPosition - trans;
88 float xDirDistance = relativePosition.dot(dirX) / lenX, yDirDistance = relativePosition.dot(dirY) / lenY, zDirDistance = relativePosition.dot(dirZ) / lenZ;
90 if(xDirDistance < -lenX) {
91 if((mActiveFaces & 2) != 2)
return -1;
95 if(xDirDistance <= lenX) {
99 if((mActiveFaces & 1) != 1)
return -1;
104 if(yDirDistance < -lenY) {
105 if((mActiveFaces & 8) != 8)
return -1;
108 if(yDirDistance <= lenY) {
112 if((mActiveFaces & 4) != 4)
return -1;
117 if(zDirDistance < -lenZ) {
118 if((mActiveFaces & 32) != 32)
return -1;
121 if(zDirDistance <= lenZ) {
125 if((mActiveFaces & 16) != 16)
return -1;
133bool CubeGravity::calcFaceGravity(
const TVec3f &rPosition, s32 area, TVec3f *pDest, f32 *pScalar)
const {
137 mPosition.getZDir(antiFaceDir);
140 mPosition.getYDir(antiFaceDir);
143 mPosition.getXDir(antiFaceDir);
146 mPosition.getXDir(antiFaceDir);
147 JGeometry::negateInternal(&antiFaceDir.x, &antiFaceDir.x);
150 mPosition.getYDir(antiFaceDir);
151 JGeometry::negateInternal(&antiFaceDir.x, &antiFaceDir.x);
154 mPosition.getZDir(antiFaceDir);
155 JGeometry::negateInternal(&antiFaceDir.x, &antiFaceDir.x);
163 mPosition.getTrans(trans);
164 MR::separateScalarAndDirection(&distance, &antiFaceDir, antiFaceDir);
165 float gravityMagnitude = antiFaceDir.dot(trans - rPosition) / distance;
166 if(gravityMagnitude < 0.f) gravityMagnitude = 0.f;
167 *pDest = antiFaceDir;
168 *pScalar = gravityMagnitude;
172void helperFunc1(
const TVec3f& a, TVec3f& b,
const TVec3f& c) {
173 JMAVECScaleAdd(a.toCVec(), c.toCVec(), b.toVec(), -a.dot(c));
183TVec3f negate(
const TVec3f& in) {
185 JGeometry::negateInternal(&in.x, &tmp.x);
189bool CubeGravity::calcEdgeGravity(
const TVec3f &rPosition, s32 area, TVec3f *pDest, f32 *pScalar)
const {
190 if(!(((area & 1) ^ ((area & 0x80000000) >> 31)) - ((area & 0x80000000) >> 31)) || area == 13)
return false;
191 TVec3f stack_140, stack_134, xDir, yDir, zDir, trans, stack_f8;
192 mPosition.getXDir(xDir);
193 mPosition.getYDir(yDir);
194 mPosition.getZDir(zDir);
198 stack_134 = negate(yDir) - zDir;
202 stack_134 = negate(xDir) - zDir;
206 stack_134 = xDir - zDir;
210 stack_134 = yDir - zDir;
214 stack_134 = negate(xDir) - yDir;
218 stack_134 = xDir + yDir;
222 stack_134 = negate(xDir).translate(yDir);
226 stack_134 = xDir.translate(yDir);
230 stack_134 = negate(yDir).translate(zDir);
234 stack_134 = negate(xDir).translate(zDir);
238 stack_134 = xDir.translate(zDir);
242 stack_134 = yDir.translate(zDir);
247 mPosition.getTrans(trans);
249 MR::normalizeOrZero(&stack_140);
250 helperFunc1(stack_140, stack_f8, stack_134 - rPosition);
251 if(stack_f8.isZero()) {
252 pDest -> normalize(stack_134 - trans);
256 *pScalar = pDest -> normalize(stack_f8);
262bool CubeGravity::calcCornerGravity(
const TVec3f &rPosition, s32 area, TVec3f *pDest, f32 *pScalar)
const {
263 TVec3f stack_140, xDir, yDir, zDir, trans;
264 mPosition.getXDir(xDir);
265 mPosition.getYDir(yDir);
266 mPosition.getZDir(zDir);
269 stack_140 = negate(xDir) - yDir - zDir;
272 stack_140 = xDir - yDir - zDir;
275 stack_140 = negate(xDir).translate(yDir) - zDir;
278 stack_140 = xDir.translate(yDir) - zDir;
281 stack_140 = (negate(xDir) - yDir).translate(zDir);
284 stack_140 = (xDir - yDir).translate(zDir);
287 stack_140 = negate(xDir).translate(yDir).translate(zDir);
290 stack_140 = xDir.translate(yDir).translate(zDir);
295 mPosition.getTrans(trans);
297 TVec3f stack_104 = stack_140 - rPosition;
298 if(stack_104.isZero()) {
300 pDest -> normalize(stack_140 - trans);
303 *pScalar = pDest -> normalize(stack_104);