diff --git a/assets/materials/static.skm.yaml b/assets/materials/static.skm.yaml index 47dbd4b..2a95ae2 100644 --- a/assets/materials/static.skm.yaml +++ b/assets/materials/static.skm.yaml @@ -207,7 +207,6 @@ materials: siz: G_IM_SIZ_4b fmt: G_IM_FMT_I - gDPSetRenderMode: G_RM_ZB_OPA_DECAL gSPGeometryMode: clear: [G_LIGHTING] set: [G_SHADE] @@ -225,7 +224,6 @@ materials: siz: G_IM_SIZ_4b fmt: G_IM_FMT_I - gDPSetRenderMode: G_RM_ZB_OPA_DECAL gSPGeometryMode: clear: [G_LIGHTING] set: [G_SHADE] @@ -243,7 +241,6 @@ materials: siz: G_IM_SIZ_4b fmt: G_IM_FMT_I - gDPSetRenderMode: G_RM_ZB_OPA_DECAL gSPGeometryMode: clear: [G_LIGHTING] set: [G_SHADE] @@ -261,7 +258,6 @@ materials: siz: G_IM_SIZ_4b fmt: G_IM_FMT_I - gDPSetRenderMode: G_RM_ZB_OPA_DECAL gSPGeometryMode: clear: [G_LIGHTING] set: [G_SHADE] diff --git a/assets/models/props/signage.blend b/assets/models/props/signage.blend index 814bb87..ae1b957 100644 Binary files a/assets/models/props/signage.blend and b/assets/models/props/signage.blend differ diff --git a/assets/test_chambers/test_chamber_00/test_chamber_00_0.blend b/assets/test_chambers/test_chamber_00/test_chamber_00_0.blend index 54d4659..792dd3b 100644 Binary files a/assets/test_chambers/test_chamber_00/test_chamber_00_0.blend and b/assets/test_chambers/test_chamber_00/test_chamber_00_0.blend differ diff --git a/skelatool64/src/definition_generator/LevelGenerator.cpp b/skelatool64/src/definition_generator/LevelGenerator.cpp index ec4d7ab..23f605c 100644 --- a/skelatool64/src/definition_generator/LevelGenerator.cpp +++ b/skelatool64/src/definition_generator/LevelGenerator.cpp @@ -432,7 +432,7 @@ void LevelGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& levelDef->AddPrimitive("triggerCount", mTriggerOutput.triggers.size()); levelDef->AddPrimitive("locationCount", mRoomOutput.namedLocations.size()); levelDef->AddPrimitive("doorCount", mRoomOutput.doors.size()); - levelDef->AddPrimitive("startLocation", mRoomOutput.FindLocationRoom("start")); + levelDef->AddPrimitive("startLocation", mRoomOutput.FindLocationIndex("start")); fileDefinition.AddDefinition(std::unique_ptr(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef)))); } \ No newline at end of file diff --git a/skelatool64/src/definition_generator/StaticGenerator.cpp b/skelatool64/src/definition_generator/StaticGenerator.cpp index bbe15b9..16d0144 100644 --- a/skelatool64/src/definition_generator/StaticGenerator.cpp +++ b/skelatool64/src/definition_generator/StaticGenerator.cpp @@ -26,6 +26,10 @@ void StaticGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& std::vector renderChunks; MeshDefinitionGenerator::AppendRenderChunks(scene, *node, fileDefinition, mSettings, renderChunks); + if (std::string((*node)->mName.C_Str()) == "@static_wall_00.013") { + std::cout << "Here" << std::endl; + } + for (auto& chunk : renderChunks) { StaticContentElement element; @@ -70,7 +74,7 @@ void StaticGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition& std::unique_ptr singleMapping(new StructureDataChunk()); int currentIndex = prevIndex; - while (currentIndex < (int)mIncludedNodes.size() && mRoomMapping.roomIndexMapping[mIncludedNodes[currentIndex]] <= roomIndex) { + while (currentIndex < (int)mOutput.staticRooms.size() && mOutput.staticRooms[currentIndex] <= roomIndex) { ++currentIndex; } diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 85f6dd8..1b8de2c 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -54,9 +54,6 @@ void graphicsCreateTask(struct GraphicsTask* targetTask, GraphicsCallback callba gDPPipeSync(renderState->dl++); gDPSetColorImage(renderState->dl++, G_IM_FMT_RGBA, G_IM_SIZ_16b, SCREEN_WD, osVirtualToPhysical(targetTask->framebuffer)); - gDPSetFillColor(renderState->dl++, (CLEAR_COLOR << 16 | - CLEAR_COLOR)); - gDPFillRectangle(renderState->dl++, 0, 0, SCREEN_WD-1, SCREEN_HT-1); gDPPipeSync(renderState->dl++); gDPSetCycleType(renderState->dl++, G_CYC_1CYCLE); diff --git a/src/physics/collision_cylinder.c b/src/physics/collision_cylinder.c index 7f9655c..f2342b0 100644 --- a/src/physics/collision_cylinder.c +++ b/src/physics/collision_cylinder.c @@ -4,6 +4,7 @@ #include "contact_solver.h" #include "collision_quad.h" #include "raycasting.h" +#include "line.h" struct ColliderCallbacks gCollisionCylinderCallbacks = { NULL, @@ -141,6 +142,149 @@ int _collisionCylinderPerpendicular(struct CollisionCylinder* cylinder, struct T return edgesToCheck; } +#define EDGE_LERP_BIAS 0.00001f + +void collisionCylinderSingleCap(struct CollisionCylinder* cylinder, struct Transform* cylinderTransform, struct Vector3* centerAxis, float capDistance, float invDot, int idOffset, struct CollisionEdge* edge, struct Vector3* edgeDirection, struct ContactConstraintState* output) { + float dOffset = vector3Dot(&cylinderTransform->position, centerAxis); + float lineDot = vector3Dot(&edge->origin, centerAxis); + + float distance = -(lineDot - (dOffset + capDistance)) * invDot; + + if (distance < EDGE_LERP_BIAS || distance > edge->length + EDGE_LERP_BIAS) { + return; + } + + struct ContactState* contact = &output->contacts[output->contactCount]; + + vector3AddScaled(&cylinderTransform->position, centerAxis, capDistance, &contact->rb); + vector3AddScaled(&edge->origin, &edge->direction, distance, &contact->ra); + + struct Vector3 offset; + vector3Sub(&contact->rb, &contact->ra, &offset); + float offsetSqrd = vector3MagSqrd(&offset); + + if (offsetSqrd > cylinder->radius * cylinder->radius) { + return; + } + + if (vector3Dot(&offset, edgeDirection) < 0.0f) { + return; + } + + if (output->contactCount == 0) { + if (offsetSqrd < 0.00001f) { + vector3Cross(centerAxis, edgeDirection, &output->normal); + } else { + vector3Sub(&contact->ra, &contact->ra, &output->normal); + } + vector3Normalize(&output->normal, &output->normal); + + output->tangentVectors[0] = *centerAxis; + vector3Cross(&output->normal, &output->tangentVectors[0], &output->tangentVectors[1]); + output->restitution = 0.0f; + output->friction = 1.0f; + } + + vector3AddScaled(&contact->rb, &output->normal, -cylinder->radius, &contact->rb); + + contact->penetration = vector3Dot(&contact->ra, &output->normal) - vector3Dot(&contact->rb, &output-> normal); + if (contact->penetration >= NEGATIVE_PENETRATION_BIAS) { + return; + } + + contact->id = idOffset; + contact->bias = 0; + contact->normalMass = 0; + contact->tangentMass[0] = 0.0f; + contact->tangentMass[1] = 0.0f; + contact->normalImpulse = 0.0f; + contact->tangentImpulse[0] = 0.0f; + contact->tangentImpulse[1] = 0.0f; + + ++output->contactCount; +} + +int collisionCylinderCap(struct CollisionCylinder* cylinder, struct Transform* cylinderTransform, struct Vector3* centerAxis, float normalDotProduct, int idOffset, struct CollisionEdge* edge, struct Vector3* edgeDirection, struct ContactConstraintState* output) { + if (fabsf(normalDotProduct) < 0.00001f) { + return 0; + } + + float invDot = 1.0f / normalDotProduct; + + collisionCylinderSingleCap(cylinder, cylinderTransform, centerAxis, cylinder->halfHeight, invDot, idOffset + 1, edge, edgeDirection, output); + collisionCylinderSingleCap(cylinder, cylinderTransform, centerAxis, -cylinder->halfHeight, invDot, idOffset + 2, edge, edgeDirection, output); + + return output->contactCount > 0; +} + +int collisionCylinderEdge(struct CollisionCylinder* cylinder, struct Transform* cylinderTransform, struct Vector3* centerAxis, float normalDotProduct, int idOffset, struct CollisionEdge* edge, struct Vector3* edgeDirection, struct ContactConstraintState* output) { + float cylinderLerp; + float edgeLerp; + + if (!lineNearestApproach(&cylinderTransform->position, centerAxis, &edge->origin, &edge->direction, &cylinderLerp, &edgeLerp)) { + return collisionCylinderCap(cylinder, cylinderTransform, centerAxis, normalDotProduct, idOffset, edge, edgeDirection, output); + } + + struct ContactState* contact = &output->contacts[output->contactCount]; + + vector3AddScaled(&cylinderTransform->position, centerAxis, cylinderLerp, &contact->rb); + vector3AddScaled(&edge->origin, &edge->direction, edgeLerp, &contact->ra); + + struct Vector3 offset; + vector3Sub(&contact->rb, &contact->ra, &offset); + float offsetSqrd = vector3MagSqrd(&offset); + + if (offsetSqrd > cylinder->radius * cylinder->radius) { + return 0; + } + + if (cylinderLerp > -cylinder->halfHeight - EDGE_LERP_BIAS && cylinderLerp < cylinder->halfHeight + EDGE_LERP_BIAS && + edgeLerp > -EDGE_LERP_BIAS && edgeLerp < edge->length + EDGE_LERP_BIAS) { + + if (vector3Dot(&offset, edgeDirection) < 0.0f) { + return 0; + } + + struct Vector3 offsetNormalized; + + if (offsetSqrd < 0.00001f) { + vector3Cross(centerAxis, &edge->direction, &offsetNormalized); + vector3Normalize(&offsetNormalized, &offsetNormalized); + } else { + vector3Scale(&offset, &offsetNormalized, 1.0f / sqrtf(offsetSqrd)); + } + + if (output->contactCount == 0) { + output->normal = offsetNormalized; + output->tangentVectors[0] = *centerAxis; + vector3Cross(&output->normal, &output->tangentVectors[0], &output->tangentVectors[1]); + output->restitution = 0.0f; + output->friction = 1.0f; + } + + vector3AddScaled(&contact->rb, &offsetNormalized, -cylinder->radius, &contact->rb); + + contact->penetration = vector3Dot(&contact->ra, &output->normal) - vector3Dot(&contact->rb, &output-> normal); + if (contact->penetration >= NEGATIVE_PENETRATION_BIAS) { + return 0; + } + + contact->id = idOffset; + contact->bias = 0; + contact->normalMass = 0; + contact->tangentMass[0] = 0.0f; + contact->tangentMass[1] = 0.0f; + contact->normalImpulse = 0.0f; + contact->tangentImpulse[0] = 0.0f; + contact->tangentImpulse[1] = 0.0f; + + ++output->contactCount; + return 1; + } + + return collisionCylinderCap(cylinder, cylinderTransform, centerAxis, normalDotProduct, idOffset, edge, edgeDirection, output); +} + int collisionCylinderCollideQuad(void* data, struct Transform* cylinderTransform, struct CollisionQuad* quad, struct ContactConstraintState* output) { struct Vector3 centerAxis; quatMultVector(&cylinderTransform->rotation, &gUp, ¢erAxis); @@ -182,6 +326,39 @@ int collisionCylinderCollideQuad(void* data, struct Transform* cylinderTransform return output->contactCount > 0; } + struct CollisionEdge edge; + struct Vector3 edgeDirection; + + if (edgesToCheck & (1 << 0)) { + edge.origin = quad->corner; + edge.direction = quad->edgeB; + edge.length = quad->edgeBLength; + vector3Negate(&quad->edgeA, &edgeDirection); + collisionCylinderEdge(cylinder, cylinderTransform, ¢erAxis, normalDotProduct, 5, &edge, &edgeDirection, output); + } + + if (edgesToCheck & (1 << 1)) { + edge.origin = quad->corner; + edge.direction = quad->edgeA; + edge.length = quad->edgeALength; + vector3Negate(&quad->edgeB, &edgeDirection); + collisionCylinderEdge(cylinder, cylinderTransform, ¢erAxis, normalDotProduct, 8, &edge, &edgeDirection, output); + } + + if (edgesToCheck & (1 << 2)) { + vector3AddScaled(&quad->corner, &quad->edgeA, quad->edgeALength, &edge.origin); + edge.direction = quad->edgeB; + edge.length = quad->edgeBLength; + collisionCylinderEdge(cylinder, cylinderTransform, ¢erAxis, normalDotProduct, 11, &edge, &edgeDirection, output); + } + + if (edgesToCheck & (1 << 3)) { + vector3AddScaled(&quad->corner, &quad->edgeB, quad->edgeBLength, &edge.origin); + edge.direction = quad->edgeA; + edge.length = quad->edgeALength; + collisionCylinderEdge(cylinder, cylinderTransform, ¢erAxis, normalDotProduct, 14, &edge, &edgeDirection, output); + } + // TODO check edges and points of quad return 0; diff --git a/src/physics/collision_quad.c b/src/physics/collision_quad.c index 11c4256..4729b27 100644 --- a/src/physics/collision_quad.c +++ b/src/physics/collision_quad.c @@ -107,12 +107,6 @@ char secondOtherAxis[] = { #define ID_FROM_AXIS_DIRS(positiveX, positiveY, positiveZ) (((positiveX) ? 1 : 0) | ((positiveY) ? 2 : 0) | ((positiveZ) ? 4 : 0)) #define ID_SEGEMENT_FROM_AXIS(axisNumber, isPositive) ((isPositive) ? 0 : (1 << axisNumber)) -struct CollisionEdge { - struct Vector3 origin; - struct Vector3 direction; - float length; -}; - // contactPoint(Pa, Da, Pb, Db) // offset = Pa - Pb // Dota = Da * offset diff --git a/src/physics/collision_quad.h b/src/physics/collision_quad.h index 18c3524..d2df10a 100644 --- a/src/physics/collision_quad.h +++ b/src/physics/collision_quad.h @@ -8,6 +8,12 @@ #define POINT_NO_OVERLAP -1 +struct CollisionEdge { + struct Vector3 origin; + struct Vector3 direction; + float length; +}; + struct CollisionQuad { struct Vector3 corner; struct Vector3 edgeA;