mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-11-26 22:00:25 +00:00
Animated surfaces can now recieve portals
This commit is contained in:
parent
26db9cf101
commit
45e6194bd0
@ -214,6 +214,8 @@ struct LevelDefinition {
|
||||
struct PortalSurface* portalSurfaces;
|
||||
// maps index of a collisionQuads to indices in portalSurfaces
|
||||
struct PortalSurfaceMappingRange* portalSurfaceMappingRange;
|
||||
struct DynamicBoxDefinition* dynamicBoxes;
|
||||
struct PortalSurfaceMappingRange* portalSurfaceDynamicMappingRange;
|
||||
u8* portalSurfaceMappingIndices;
|
||||
struct Trigger* triggers;
|
||||
struct Cutscene* cutscenes;
|
||||
@ -230,10 +232,10 @@ struct LevelDefinition {
|
||||
struct BoxDropperDefinition* boxDroppers;
|
||||
struct AnimationInfo* animations;
|
||||
struct SwitchDefinition* switches;
|
||||
struct DynamicBoxDefinition* dynamicBoxes;
|
||||
short collisionQuadCount;
|
||||
short staticContentCount;
|
||||
short portalSurfaceCount;
|
||||
short dynamicBoxCount;
|
||||
short triggerCount;
|
||||
short cutsceneCount;
|
||||
short locationCount;
|
||||
@ -248,7 +250,6 @@ struct LevelDefinition {
|
||||
short boxDropperCount;
|
||||
short animationInfoCount;
|
||||
short switchCount;
|
||||
short dynamicBoxCount;
|
||||
short startLocation;
|
||||
};
|
||||
|
||||
|
@ -55,6 +55,7 @@ struct LevelDefinition* levelFixPointers(struct LevelDefinition* from, int point
|
||||
}
|
||||
|
||||
result->portalSurfaceMappingRange = ADJUST_POINTER_POS(result->portalSurfaceMappingRange, pointerOffset);
|
||||
result->portalSurfaceDynamicMappingRange = ADJUST_POINTER_POS(result->portalSurfaceDynamicMappingRange, pointerOffset);
|
||||
result->portalSurfaceMappingIndices = ADJUST_POINTER_POS(result->portalSurfaceMappingIndices, pointerOffset);
|
||||
result->triggers = ADJUST_POINTER_POS(result->triggers, pointerOffset);
|
||||
result->cutscenes = ADJUST_POINTER_POS(result->cutscenes, pointerOffset);
|
||||
|
@ -51,7 +51,7 @@ void sceneInitDynamicColliders(struct Scene* scene) {
|
||||
colliderType[i].bounce = 0.5f;
|
||||
colliderType[i].friction = 0.5f;
|
||||
colliderType[i].callbacks = &gCollisionBoxCallbacks;
|
||||
collisionObjectInit(&colliders[i], &colliderType[i], &body[i], 1.0f, COLLISION_LAYERS_TANGIBLE);
|
||||
collisionObjectInit(&colliders[i], &colliderType[i], &body[i], 1.0f, COLLISION_LAYERS_TANGIBLE | COLLISION_LAYERS_STATIC);
|
||||
rigidBodyMarkKinematic(&body[i]);
|
||||
|
||||
body[i].currentRoom = gCurrentLevel->dynamicBoxes[i].roomIndex;
|
||||
@ -446,7 +446,18 @@ void sceneUpdate(struct Scene* scene) {
|
||||
}
|
||||
}
|
||||
|
||||
int sceneOpenPortal(struct Scene* scene, struct Transform* at, int portalIndex, struct PortalSurfaceMappingRange surfaceMapping, struct CollisionObject* collisionObject, int roomIndex) {
|
||||
int sceneOpenPortal(struct Scene* scene, struct Transform* at, struct Transform* relativeTo, int portalIndex, struct PortalSurfaceMappingRange surfaceMapping, struct CollisionObject* collisionObject, int roomIndex) {
|
||||
struct Transform finalAt;
|
||||
|
||||
if (relativeTo) {
|
||||
struct Transform relativeInverse;
|
||||
struct Transform relativePreScale = *relativeTo;
|
||||
vector3Scale(&relativePreScale.position, &relativePreScale.position, 1.0f / SCENE_SCALE);
|
||||
transformInvert(&relativePreScale, &relativeInverse);
|
||||
transformConcat(&relativeInverse, at, &finalAt);
|
||||
} else {
|
||||
finalAt = *at;
|
||||
}
|
||||
|
||||
for (int indexIndex = surfaceMapping.minPortalIndex; indexIndex < surfaceMapping.maxPortalIndex; ++indexIndex) {
|
||||
int surfaceIndex = gCurrentLevel->portalSurfaceMappingIndices[indexIndex];
|
||||
@ -455,10 +466,18 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int portalIndex,
|
||||
|
||||
struct Portal* portal = &scene->portals[portalIndex];
|
||||
|
||||
if (portalAttachToSurface(portal, existingSurface, surfaceIndex, at)) {
|
||||
if (portalAttachToSurface(portal, existingSurface, surfaceIndex, &finalAt)) {
|
||||
soundPlayerPlay(soundsPortalOpen2, 1.0f, 1.0f, &at->position);
|
||||
|
||||
// the portal position may have been adjusted
|
||||
if (relativeTo) {
|
||||
struct Transform relativePreScale = *relativeTo;
|
||||
vector3Scale(&relativePreScale.position, &relativePreScale.position, 1.0f / SCENE_SCALE);
|
||||
transformConcat(&relativePreScale, &finalAt, &portal->transform);
|
||||
} else {
|
||||
portal->transform = finalAt;
|
||||
}
|
||||
|
||||
portal->transform = *at;
|
||||
portal->roomIndex = roomIndex;
|
||||
portal->scale = 0.0f;
|
||||
gCollisionScene.portalTransforms[portalIndex] = &portal->transform;
|
||||
@ -477,6 +496,34 @@ int sceneOpenPortal(struct Scene* scene, struct Transform* at, int portalIndex,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sceneDynamicBoxIndex(struct Scene* scene, struct CollisionObject* hitObject) {
|
||||
if (hitObject < scene->dynamicColliders || hitObject >= scene->dynamicColliders + gCurrentLevel->dynamicBoxCount) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return hitObject - scene->dynamicColliders;
|
||||
}
|
||||
|
||||
int sceneDetermineSurfaceMapping(struct Scene* scene, struct CollisionObject* hitObject, struct PortalSurfaceMappingRange* mappingRangeOut, struct Transform** relativeToOut) {
|
||||
int quadIndex = levelQuadIndex(hitObject);
|
||||
|
||||
if (quadIndex != -1) {
|
||||
*mappingRangeOut = gCurrentLevel->portalSurfaceMappingRange[quadIndex];
|
||||
*relativeToOut = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dynamicBoxIndex = sceneDynamicBoxIndex(scene, hitObject);
|
||||
|
||||
if (dynamicBoxIndex != -1) {
|
||||
*mappingRangeOut = gCurrentLevel->portalSurfaceDynamicMappingRange[dynamicBoxIndex];
|
||||
*relativeToOut = sceneAnimatorTransformForIndex(&scene->animator, gCurrentLevel->dynamicBoxes[dynamicBoxIndex].transformIndex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* playerUp, int portalIndex, int roomIndex) {
|
||||
struct RaycastHit hit;
|
||||
|
||||
@ -484,9 +531,10 @@ int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* player
|
||||
return 0;
|
||||
}
|
||||
|
||||
int quadIndex = levelQuadIndex(hit.object);
|
||||
struct PortalSurfaceMappingRange mappingRange;
|
||||
struct Transform* relativeTo = NULL;
|
||||
|
||||
if (quadIndex == -1) {
|
||||
if (!sceneDetermineSurfaceMapping(scene, hit.object, &mappingRange, &relativeTo)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -514,7 +562,7 @@ int sceneFirePortal(struct Scene* scene, struct Ray* ray, struct Vector3* player
|
||||
quatLook(&hitDirection, &upDir, &portalLocation.rotation);
|
||||
}
|
||||
|
||||
return sceneOpenPortal(scene, &portalLocation, portalIndex, gCurrentLevel->portalSurfaceMappingRange[quadIndex], &gCurrentLevel->collisionQuads[quadIndex], hit.roomIndex);
|
||||
return sceneOpenPortal(scene, &portalLocation, relativeTo, portalIndex, mappingRange, hit.object, hit.roomIndex);
|
||||
}
|
||||
|
||||
void sceneClosePortal(struct Scene* scene, int portalIndex) {
|
||||
|
@ -21,6 +21,7 @@ sk_definition_writer.add_definition("level", "struct LevelDefinition", "_geo", {
|
||||
portalSurfaces = sk_definition_writer.reference_to(portal_surfaces.portal_surfaces, 1),
|
||||
portalSurfaceCount = #portal_surfaces.portal_surfaces,
|
||||
portalSurfaceMappingRange = sk_definition_writer.reference_to(portal_surfaces.portal_mapping_range, 1),
|
||||
portalSurfaceDynamicMappingRange = sk_definition_writer.reference_to(portal_surfaces.dynamic_mapping_range, 1),
|
||||
portalSurfaceMappingIndices = sk_definition_writer.reference_to(portal_surfaces.portal_mapping_data, 1),
|
||||
triggers = sk_definition_writer.reference_to(trigger.triggers, 1),
|
||||
triggerCount = #trigger.triggers,
|
||||
|
@ -4,18 +4,19 @@ local animation = require('tools.level_scripts.animation')
|
||||
local room_export = require('tools.level_scripts.room_export')
|
||||
|
||||
local dynamic_boxes = {}
|
||||
local dynamic_boxes_original = {}
|
||||
|
||||
local function build_dynamic_box(box)
|
||||
local parent_node_index = animation.get_bone_index_for_node(box.node)
|
||||
|
||||
if not parent_node_index then
|
||||
return nil
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
local parent_node = animation.get_bone_for_index(parent_node_index)
|
||||
|
||||
if not parent_node then
|
||||
return nil
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
local relative_transform = parent_node.full_transformation:inverse() * box.node.full_transformation
|
||||
@ -31,14 +32,18 @@ local function build_dynamic_box(box)
|
||||
rotation,
|
||||
room_export.node_nearest_room_index(box.node),
|
||||
parent_node_index - 1,
|
||||
}, {
|
||||
node = box.node,
|
||||
parent_node_index = parent_node_index,
|
||||
}
|
||||
end
|
||||
|
||||
for _, box in pairs(sk_scene.nodes_for_type('@dynamic_box')) do
|
||||
local dynamic_box = build_dynamic_box(box)
|
||||
local dynamic_box, dynamic_box_original = build_dynamic_box(box)
|
||||
|
||||
if dynamic_box then
|
||||
table.insert(dynamic_boxes, dynamic_box)
|
||||
table.insert(dynamic_boxes_original, dynamic_box_original)
|
||||
end
|
||||
|
||||
end
|
||||
@ -47,4 +52,5 @@ sk_definition_writer.add_definition('dynamic_boxes', 'struct DynamicBoxDefinitio
|
||||
|
||||
return {
|
||||
dynamic_boxes = dynamic_boxes,
|
||||
dynamic_boxes_original = dynamic_boxes_original,
|
||||
}
|
@ -4,6 +4,7 @@ local sk_input = require('sk_input')
|
||||
local sk_math = require('sk_math')
|
||||
local sk_mesh = require('sk_mesh')
|
||||
local sk_definition_writer = require('sk_definition_writer')
|
||||
local dynamic_collision_export = require('tools.level_scripts.dynamic_collision_export')
|
||||
|
||||
local portal_surfaces = {}
|
||||
|
||||
@ -216,6 +217,7 @@ end
|
||||
|
||||
local portal_mapping_data = {}
|
||||
local portal_mapping_range = {}
|
||||
local dynamic_mapping_range = {}
|
||||
|
||||
local mapping_index = 0
|
||||
|
||||
@ -227,9 +229,13 @@ for _, quad in pairs(collision_export.colliders) do
|
||||
collision_with_padding.max = collision_with_padding.max + 0.1
|
||||
|
||||
for static_index, surface in pairs(static_export.static_nodes) do
|
||||
if is_coplanar_portal_surface(quad, surface.mesh, collision_with_padding) then
|
||||
table.insert(portal_mapping_data, static_to_portable_surface_mapping[static_index])
|
||||
mapping_index = mapping_index + 1
|
||||
if not surface.transform_index and is_coplanar_portal_surface(quad, surface.mesh, collision_with_padding) then
|
||||
local portal_surface_index = static_to_portable_surface_mapping[static_index]
|
||||
|
||||
if portal_surface_index ~= -1 then
|
||||
table.insert(portal_mapping_data, static_to_portable_surface_mapping[static_index])
|
||||
mapping_index = mapping_index + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -240,11 +246,37 @@ for _, quad in pairs(collision_export.colliders) do
|
||||
table.insert(portal_mapping_range, {start_mapping_index, mapping_index})
|
||||
end
|
||||
|
||||
for _, box in pairs(dynamic_collision_export.dynamic_boxes_original) do
|
||||
local start_mapping_index = mapping_index
|
||||
|
||||
for static_index, surface in pairs(static_export.static_nodes) do
|
||||
-- simple hack for now. If collider and a portal surface share
|
||||
-- the same transform then the portal surface is assumed to be
|
||||
-- attached to the collider
|
||||
if surface.transform_index == box.parent_node_index then
|
||||
local portal_surface_index = static_to_portable_surface_mapping[static_index]
|
||||
|
||||
if portal_surface_index ~= -1 then
|
||||
table.insert(portal_mapping_data, static_to_portable_surface_mapping[static_index])
|
||||
mapping_index = mapping_index + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if mapping_index > 255 then
|
||||
error("mapping_index was greater than 255")
|
||||
end
|
||||
|
||||
table.insert(dynamic_mapping_range, {start_mapping_index, mapping_index})
|
||||
end
|
||||
|
||||
sk_definition_writer.add_definition("mapping_indices", "u8[]", "_geo", portal_mapping_data)
|
||||
sk_definition_writer.add_definition("collider_to_surface", "struct PortalSurfaceMappingRange[]", "_geo", portal_mapping_range)
|
||||
sk_definition_writer.add_definition("dynamic_collider_to_surface", "struct PortalSurfaceMappingRange[]", "_geo", dynamic_mapping_range)
|
||||
|
||||
return {
|
||||
portal_surfaces = portal_surfaces,
|
||||
portal_mapping_data = portal_mapping_data,
|
||||
portal_mapping_range = portal_mapping_range,
|
||||
dynamic_mapping_range = dynamic_mapping_range,
|
||||
}
|
Loading…
Reference in New Issue
Block a user