diff --git a/assets/materials/static.skm.yaml b/assets/materials/static.skm.yaml index 23103ff..2820088 100644 --- a/assets/materials/static.skm.yaml +++ b/assets/materials/static.skm.yaml @@ -298,6 +298,7 @@ materials: gDPSetCombineMode: G_CC_DECALRGB gDPSetCycleType: G_CYC_1CYCLE + gDPSetTextureFilter: G_TF_BILERP radio: gDPSetTile: 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 2396fe3..8e6da37 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/src/decor/decor_object_list.c b/src/decor/decor_object_list.c index 8550bc0..20bb25e 100644 --- a/src/decor/decor_object_list.c +++ b/src/decor/decor_object_list.c @@ -15,11 +15,14 @@ struct Vector2 gCylinderColliderEdgeVectors[] = { {0.707f, -0.707f}, }; +struct CollisionQuad gCyliderColliderFaces[8]; + struct CollisionCylinder gCylinderCollider = { 0.3f, 0.35f, gCylinderColliderEdgeVectors, sizeof(gCylinderColliderEdgeVectors) / sizeof(*gCylinderColliderEdgeVectors), + gCyliderColliderFaces, }; struct CollisionBox gRadioCollider = { diff --git a/src/physics/collision_cylinder.c b/src/physics/collision_cylinder.c index d3d4e58..7fa3a00 100644 --- a/src/physics/collision_cylinder.c +++ b/src/physics/collision_cylinder.c @@ -6,6 +6,7 @@ #include "raycasting.h" #include "line.h" #include "../math/vector2.h" +#include "./raycasting.h" struct ColliderCallbacks gCollisionCylinderCallbacks = { raycastCylinder, @@ -14,6 +15,59 @@ struct ColliderCallbacks gCollisionCylinderCallbacks = { collisionCylinderMinkowsiSum, }; +void collisionCylinderBoxCheckForFaces(struct CollisionCylinder* cylinder) { + if (cylinder->outsideFaces[0].edgeALength > 0.0f) { + return; + } + + struct Vector2 prevPoint; + vector2Scale(&cylinder->edgeVectors[cylinder->edgeCount - 1], -cylinder->radius, &prevPoint); + + for (int i = 0; i < (cylinder->edgeCount << 1); ++i) { + struct Vector2 currPoint; + vector2Scale(&cylinder->edgeVectors[i % cylinder->edgeCount], i >= cylinder->edgeCount ? -cylinder->radius : cylinder->radius, &currPoint); + + struct CollisionQuad* quad = &cylinder->outsideFaces[i]; + + quad->corner.x = prevPoint.x; + quad->corner.y = -cylinder->halfHeight; + quad->corner.z = prevPoint.y; + + struct Vector3 toEdge; + + toEdge.x = currPoint.x; + toEdge.y = -cylinder->halfHeight; + toEdge.z = currPoint.y; + + vector3Sub(&toEdge, &quad->corner, &quad->edgeA); + quad->edgeALength = sqrtf(vector3MagSqrd(&quad->edgeA)); + vector3Scale(&quad->edgeA, &quad->edgeA, 1.0f / quad->edgeALength); + + quad->edgeB = gUp; + quad->edgeBLength = cylinder->halfHeight * 2.0f; + + vector3Cross(&quad->edgeA, &quad->edgeB, &quad->plane.normal); + + if (vector3Dot(&quad->plane.normal, &quad->corner) < 0.0f) { + struct Vector3 tmpEdge = quad->edgeA; + quad->edgeA = quad->edgeB; + quad->edgeB = tmpEdge; + + float tmpLen = quad->edgeALength; + quad->edgeALength = quad->edgeBLength; + quad->edgeBLength = tmpLen; + + vector3Negate(&quad->plane.normal, &quad->plane.normal); + } + + quad->plane.d = -vector3Dot(&quad->plane.normal, &quad->corner); + + quad->enabledEdges = 0; + + prevPoint = currPoint; + } +} + float collisionCylinderSolidMofI(struct ColliderTypeData* typeData, float mass) { struct CollisionCylinder* cylinder = (struct CollisionCylinder*)typeData->data; @@ -119,5 +173,16 @@ int collisionCylinderRaycast(struct CollisionObject* cylinderObject, struct Ray* basisUnRotate(&cylinderObject->body->rotationBasis, &ray->dir, &localRay.dir); basisUnRotate(&cylinderObject->body->rotationBasis, &offset, &localRay.origin); - return 1; + collisionCylinderBoxCheckForFaces(cylinder); + + struct RaycastHit localHit; + + for (int i = 0; i < (cylinder->edgeCount << 1); ++i) { + if (raycastQuadShape(&cylinder->outsideFaces[i], &localRay, maxDistance, &localHit)) { + // TODO transform hit + return 1; + } + } + + return 0; } \ No newline at end of file diff --git a/src/physics/collision_cylinder.h b/src/physics/collision_cylinder.h index 80a9265..dc7fa88 100644 --- a/src/physics/collision_cylinder.h +++ b/src/physics/collision_cylinder.h @@ -10,6 +10,7 @@ struct CollisionCylinder { float halfHeight; struct Vector2* edgeVectors; int edgeCount; + struct CollisionQuad* outsideFaces; }; extern struct ColliderCallbacks gCollisionCylinderCallbacks; diff --git a/src/player/player.c b/src/player/player.c index c9210fb..b905568 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -27,11 +27,14 @@ struct Vector2 gPlayerColliderEdgeVectors[] = { {0.707f, -0.707f}, }; +struct CollisionQuad gPlayerColliderFaces[8]; + struct CollisionCylinder gPlayerCollider = { 0.25f, 0.7f, gPlayerColliderEdgeVectors, sizeof(gPlayerColliderEdgeVectors) / sizeof(*gPlayerColliderEdgeVectors), + gPlayerColliderFaces, }; struct ColliderTypeData gPlayerColliderData = { diff --git a/src/scene/button.c b/src/scene/button.c index ebde373..6290c18 100644 --- a/src/scene/button.c +++ b/src/scene/button.c @@ -18,11 +18,14 @@ struct Vector2 gButtonCylinderEdgeVectors[] = { {0.707f, -0.707f}, }; +struct CollisionQuad gButtonCylinderFaces[8]; + struct CollisionCylinder gButtonCylinder = { 0.5f, 0.3f, gButtonCylinderEdgeVectors, sizeof(gButtonCylinderEdgeVectors) / sizeof(*gButtonCylinderEdgeVectors), + gButtonCylinderFaces, }; struct ColliderTypeData gButtonCollider = { diff --git a/src/scene/portal.c b/src/scene/portal.c index 4bd745e..d46494a 100644 --- a/src/scene/portal.c +++ b/src/scene/portal.c @@ -44,6 +44,8 @@ struct Quaternion gVerticalFlip = {0.0f, 1.0f, 0.0f, 0.0f}; #define STARTING_RENDER_DEPTH 2 +#define PORTAL_CLIPPING_PLANE_BIAS (SCENE_SCALE * 0.25f) + void renderPropsInit(struct RenderProps* props, struct Camera* camera, float aspectRatio, struct RenderState* renderState, u16 roomIndex) { props->camera = *camera; props->aspectRatio = aspectRatio; @@ -150,7 +152,7 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru if (toPortal < fromPortal) { vector3Negate(&next->cullingInfo.clippingPlanes[4].normal, &next->cullingInfo.clippingPlanes[4].normal); } - next->cullingInfo.clippingPlanes[4].d = -vector3Dot(&next->cullingInfo.clippingPlanes[4].normal, &toPortal->position) * SCENE_SCALE; + next->cullingInfo.clippingPlanes[4].d = -vector3Dot(&next->cullingInfo.clippingPlanes[4].normal, &toPortal->position) * SCENE_SCALE - PORTAL_CLIPPING_PLANE_BIAS; next->currentDepth = current->currentDepth - 1; next->fromPortalIndex = toPortal < fromPortal ? 0 : 1;