scene_serialize: serialize and deserialize security cameras

security_camera: replaced hardcoded mass of 1.0f with SECURITY_CAMERA_RIGID_BODY_MASS definition in header. added utility function to calculate security_camera moment_of_inertia, making it accessible to scene_serialize for deserialization due to rigidBodyUnmarkKinematic
This commit is contained in:
Deconimus 2024-03-04 02:09:10 +01:00
parent e2b3fcdd8d
commit b23e22bb34
3 changed files with 80 additions and 6 deletions

View file

@ -319,7 +319,6 @@ void launcherSerialize(struct Serializer* serializer, SerializeAction action, st
action(serializer, &launcher->currentBall.targetSpeed, sizeof(float));
action(serializer, &launcher->currentBall.flags, sizeof(short));
if (!ballIsActive(&launcher->currentBall) || ballIsCaught(&launcher->currentBall)) {
continue;
}
@ -447,9 +446,72 @@ void sceneAnimatorDeserialize(struct Serializer* serializer, struct Scene* scene
}
}
#define INCLUDE_SAVEFILE_ALIGH_CHECKS 0
void securityCameraSerialize(struct Serializer* serializer, SerializeAction action, struct Scene* scene) {
u8 serializedCount = 0;
short heldCam = -1;
for (int i = 0; i < scene->securityCameraCount; ++i) {
struct SecurityCamera* cam = &scene->securityCameras[i];
if (!(cam->rigidBody.flags & RigidBodyIsKinematic)) {
if (&cam->collisionObject == scene->player.grabConstraint.object) {
heldCam = serializedCount;
}
++serializedCount;
}
}
action(serializer, &serializedCount, sizeof(u8));
action(serializer, &heldCam, sizeof(short));
for (int i = 0; i < scene->securityCameraCount; ++i) {
struct SecurityCamera* cam = &scene->securityCameras[i];
if (!(cam->rigidBody.flags & RigidBodyIsKinematic)) {
u8 index = i;
action(serializer, &index, sizeof(u8));
action(serializer, &cam->rigidBody.transform, sizeof(struct PartialTransform));
action(serializer, &cam->rigidBody.velocity, sizeof(struct Vector3));
action(serializer, &cam->rigidBody.angularVelocity, sizeof(struct Vector3));
action(serializer, &cam->rigidBody.flags, sizeof(enum RigidBodyFlags));
action(serializer, &cam->rigidBody.currentRoom, sizeof(short));
}
}
}
#if INCLUDE_SAVEFILE_ALIGH_CHECKS
void securityCameraDeserialize(struct Serializer* serializer, struct Scene* scene) {
u8 serializedCount;
serializeRead(serializer, &serializedCount, sizeof(u8));
short heldCam;
serializeRead(serializer, &heldCam, sizeof(short));
for (int i = 0; i < serializedCount; ++i) {
u8 index;
serializeRead(serializer, &index, sizeof(u8));
if (index >= scene->securityCameraCount) {
continue;
}
struct SecurityCamera* cam = &scene->securityCameras[index];
rigidBodyUnmarkKinematic(&cam->rigidBody, SECURITY_CAMERA_RIGID_BODY_MASS, securityCameraMofI());
serializeRead(serializer, &cam->rigidBody.transform, sizeof(struct PartialTransform));
serializeRead(serializer, &cam->rigidBody.velocity, sizeof(struct Vector3));
serializeRead(serializer, &cam->rigidBody.angularVelocity, sizeof(struct Vector3));
serializeRead(serializer, &cam->rigidBody.flags, sizeof(enum RigidBodyFlags));
serializeRead(serializer, &cam->rigidBody.currentRoom, sizeof(short));
cam->rigidBody.flags &= ~RigidBodyIsSleeping;
cam->rigidBody.sleepFrames = IDLE_SLEEP_FRAMES;
if (heldCam == i) {
playerSetGrabbing(&scene->player, &cam->collisionObject);
}
}
}
#define INCLUDE_SAVEFILE_ALIGN_CHECKS 0
#if INCLUDE_SAVEFILE_ALIGN_CHECKS
#define WRITE_ALIGN_CHECK {action(serializer, &currentAlign, 1); ++currentAlign;}
#define READ_ALIGN_CHECK {serializeRead(serializer, &currentAlign, 1); if (currentAlign != expectedAlign) gdbBreak(); ++expectedAlign;}
#else
@ -458,7 +520,7 @@ void sceneAnimatorDeserialize(struct Serializer* serializer, struct Scene* scene
#endif
void sceneSerialize(struct Serializer* serializer, SerializeAction action, struct Scene* scene) {
#if INCLUDE_SAVEFILE_ALIGH_CHECKS
#if INCLUDE_SAVEFILE_ALIGN_CHECKS
char currentAlign = 0;
#endif
playerSerialize(serializer, action, &scene->player);
@ -485,10 +547,12 @@ void sceneSerialize(struct Serializer* serializer, SerializeAction action, struc
WRITE_ALIGN_CHECK;
switchSerialize(serializer, action, scene);
WRITE_ALIGN_CHECK;
securityCameraSerialize(serializer, action, scene);
WRITE_ALIGN_CHECK;
}
void sceneDeserialize(struct Serializer* serializer, struct Scene* scene) {
#if INCLUDE_SAVEFILE_ALIGH_CHECKS
#if INCLUDE_SAVEFILE_ALIGN_CHECKS
char currentAlign = 0;
char expectedAlign = 0;
#endif
@ -516,6 +580,8 @@ void sceneDeserialize(struct Serializer* serializer, struct Scene* scene) {
READ_ALIGN_CHECK;
switchSerialize(serializer, serializeRead, scene);
READ_ALIGN_CHECK;
securityCameraDeserialize(serializer, scene);
READ_ALIGN_CHECK;
for (int i = 0; i < scene->doorCount; ++i) {
doorCheckForOpenState(&scene->doors[i]);

View file

@ -168,7 +168,7 @@ void securityCamerasCheckPortal(struct SecurityCamera* securityCameras, int came
continue;
}
if (box3DHasOverlap(&camera->collisionObject.boundingBox, portalBox)) {
rigidBodyUnmarkKinematic(&camera->rigidBody, 1.0f, collisionBoxSolidMofI(&gSecurityCameraCollider, 1.0f));
rigidBodyUnmarkKinematic(&camera->rigidBody, SECURITY_CAMERA_RIGID_BODY_MASS, securityCameraMofI());
camera->collisionObject.collisionLayers |= COLLISION_LAYERS_GRABBABLE;
camera->rigidBody.flags |= RigidBodyFlagsGrabbable;
@ -178,4 +178,8 @@ void securityCamerasCheckPortal(struct SecurityCamera* securityCameras, int came
}
}
}
}
float securityCameraMofI() {
return collisionBoxSolidMofI(&gSecurityCameraCollider, SECURITY_CAMERA_RIGID_BODY_MASS);
}

View file

@ -5,6 +5,8 @@
#include "../levels/level_definition.h"
#include "../sk64/skelatool_armature.h"
#define SECURITY_CAMERA_RIGID_BODY_MASS 1.0f
struct SecurityCamera {
struct CollisionObject collisionObject;
struct RigidBody rigidBody;
@ -18,4 +20,6 @@ void securityCameraUpdate(struct SecurityCamera* securityCamera);
void securityCamerasCheckPortal(struct SecurityCamera* securityCameras, int cameraCount, struct Box3D* portalBox);
float securityCameraMofI(); // utility for serialization
#endif