mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
work on cylinder collider
This commit is contained in:
parent
4956892ae1
commit
7c240a8393
|
@ -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]
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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<FileDefinition>(new DataFileDefinition("struct LevelDefinition", fileDefinition.GetUniqueName("level"), false, "_geo", std::move(levelDef))));
|
||||
}
|
|
@ -26,6 +26,10 @@ void StaticGenerator::GenerateDefinitions(const aiScene* scene, CFileDefinition&
|
|||
std::vector<RenderChunk> 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<StructureDataChunk> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue