tilting_inverted_pyramid.inc.c (3997B)
1 2 /** 3 * This is the behavior file for the tilting inverted pyramids in BitFS/LLL. 4 * The object essentially just tilts and moves Mario with it. 5 */ 6 7 /** 8 * Creates a transform matrix on a variable passed in from given normals 9 * and the object's position. 10 */ 11 void create_transform_from_normals(Mat4 transform, f32 xNorm, f32 yNorm, f32 zNorm) { 12 Vec3f normal; 13 Vec3f pos; 14 15 pos[0] = o->oPosX; 16 pos[1] = o->oPosY; 17 pos[2] = o->oPosZ; 18 19 normal[0] = xNorm; 20 normal[1] = yNorm; 21 normal[2] = zNorm; 22 23 mtxf_align_terrain_normal(transform, normal, pos, 0); 24 } 25 26 /** 27 * Initialize the object's transform matrix with Y being up. 28 */ 29 void bhv_platform_normals_init(void) { 30 Mat4 *transform = &o->transform; 31 32 o->oTiltingPyramidNormalX = 0.0f; 33 o->oTiltingPyramidNormalY = 1.0f; 34 o->oTiltingPyramidNormalZ = 0.0f; 35 36 create_transform_from_normals(*transform, 0.0f, 1.0f, 0.0f); 37 } 38 39 /** 40 * Returns a value that is src incremented/decremented by inc towards goal 41 * until goal is reached. Does not overshoot. 42 */ 43 f32 approach_by_increment(f32 goal, f32 src, f32 inc) { 44 f32 newVal; 45 46 if (src <= goal) { 47 if (goal - src < inc) { 48 newVal = goal; 49 } else { 50 newVal = src + inc; 51 } 52 } else if (goal - src > -inc) { 53 newVal = goal; 54 } else { 55 newVal = src - inc; 56 } 57 58 return newVal; 59 } 60 61 /** 62 * Main behavior for the tilting pyramids in LLL/BitFS. These platforms calculate rough normals from Mario's position, 63 * then gradually tilt back moving Mario with them. 64 */ 65 void bhv_tilting_inverted_pyramid_loop(void) { 66 f32 dx; 67 f32 dy; 68 f32 dz; 69 f32 d; 70 71 Vec3f dist; 72 Vec3f posBeforeRotation; 73 Vec3f posAfterRotation; 74 75 // Mario's position 76 f32 mx; 77 f32 my; 78 f32 mz; 79 80 s32 marioOnPlatform = FALSE; 81 UNUSED u8 filler1[4]; 82 Mat4 *transform = &o->transform; 83 UNUSED u8 filler2[28]; 84 85 if (gMarioObject->platform == o) { 86 get_mario_pos(&mx, &my, &mz); 87 88 dist[0] = gMarioObject->oPosX - o->oPosX; 89 dist[1] = gMarioObject->oPosY - o->oPosY; 90 dist[2] = gMarioObject->oPosZ - o->oPosZ; 91 linear_mtxf_mul_vec3f(*transform, posBeforeRotation, dist); 92 93 dx = gMarioObject->oPosX - o->oPosX; 94 dy = 500.0f; 95 dz = gMarioObject->oPosZ - o->oPosZ; 96 d = sqrtf(dx * dx + dy * dy + dz * dz); 97 98 //! Always true since dy = 500, making d >= 500. 99 if (d != 0.0f) { 100 // Normalizing 101 d = 1.0 / d; 102 dx *= d; 103 dy *= d; 104 dz *= d; 105 } else { 106 dx = 0.0f; 107 dy = 1.0f; 108 dz = 0.0f; 109 } 110 111 if (o->oTiltingPyramidMarioOnPlatform == TRUE) { 112 marioOnPlatform++; 113 } 114 115 o->oTiltingPyramidMarioOnPlatform = TRUE; 116 } else { 117 dx = 0.0f; 118 dy = 1.0f; 119 dz = 0.0f; 120 o->oTiltingPyramidMarioOnPlatform = FALSE; 121 } 122 123 // Approach the normals by 0.01f towards the new goal, then create a transform matrix and orient the object. 124 // Outside of the other conditionals since it needs to tilt regardless of whether Mario is on. 125 o->oTiltingPyramidNormalX = approach_by_increment(dx, o->oTiltingPyramidNormalX, 0.01f); 126 o->oTiltingPyramidNormalY = approach_by_increment(dy, o->oTiltingPyramidNormalY, 0.01f); 127 o->oTiltingPyramidNormalZ = approach_by_increment(dz, o->oTiltingPyramidNormalZ, 0.01f); 128 create_transform_from_normals(*transform, o->oTiltingPyramidNormalX, o->oTiltingPyramidNormalY, o->oTiltingPyramidNormalZ); 129 130 // If Mario is on the platform, adjust his position for the platform tilt. 131 if (marioOnPlatform) { 132 linear_mtxf_mul_vec3f(*transform, posAfterRotation, dist); 133 mx += posAfterRotation[0] - posBeforeRotation[0]; 134 my += posAfterRotation[1] - posBeforeRotation[1]; 135 mz += posAfterRotation[2] - posBeforeRotation[2]; 136 set_mario_pos(mx, my, mz); 137 } 138 139 o->header.gfx.throwMatrix = transform; 140 }