Start work on collision cylinder
This commit is contained in:
parent
334b1561b8
commit
a4f23b8c23
|
@ -57,7 +57,6 @@ where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where blender
|
||||||
|
|
||||||
## Current TODO list
|
## Current TODO list
|
||||||
|
|
||||||
refactor dynamic rendering
|
|
||||||
cylinder collider type
|
cylinder collider type
|
||||||
cube dispenser
|
cube dispenser
|
||||||
logic and trigger wiring
|
logic and trigger wiring
|
108
src/physics/collision_cylinder.c
Normal file
108
src/physics/collision_cylinder.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#include "collision_cylinder.h"
|
||||||
|
|
||||||
|
#include "../math/mathf.h"
|
||||||
|
#include "contact_solver.h"
|
||||||
|
#include "collision_quad.h"
|
||||||
|
|
||||||
|
int _collisionCylinderParallel(struct CollisionCylinder* cylinder, struct Transform* cylinderTransform, struct Vector3* centerAxis, struct Vector3* crossAxis, float normalDotProduct, struct CollisionQuad* quad, struct ContactConstraintState* output) {
|
||||||
|
struct Vector3 edgeEndpoint;
|
||||||
|
vector3AddScaled(&cylinderTransform->position, centerAxis, normalDotProduct > 0.0f ? -cylinder->halfHeight : cylinder->halfHeight, &edgeEndpoint);
|
||||||
|
vector3Add(&edgeEndpoint, crossAxis, &edgeEndpoint);
|
||||||
|
|
||||||
|
float edgeDistance = planePointDistance(&quad->plane, &edgeEndpoint);
|
||||||
|
|
||||||
|
if (edgeDistance > NEGATIVE_PENETRATION_BIAS) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int edgesToCheck = collisionQuadDetermineEdges(&edgeEndpoint, quad);
|
||||||
|
|
||||||
|
output->contactCount = 0;
|
||||||
|
|
||||||
|
if (!edgesToCheck) {
|
||||||
|
collisionQuadInitializeNormalContact(quad, output);
|
||||||
|
|
||||||
|
struct ContactState* contact = &output->contacts[output->contactCount];
|
||||||
|
|
||||||
|
++output->contactCount;
|
||||||
|
|
||||||
|
vector3Sub(&edgeEndpoint, &cylinderTransform->position, &contact->rb);
|
||||||
|
vector3AddScaled(&edgeEndpoint, &quad->plane.normal, -edgeDistance, &contact->ra);
|
||||||
|
|
||||||
|
contact->id = 0;
|
||||||
|
contact->penetration = edgeDistance;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector3AddScaled(&edgeEndpoint, centerAxis, (normalDotProduct > 0.0f ? 2.0f : -2.0f) * cylinder->halfHeight, &edgeEndpoint);
|
||||||
|
edgeDistance = planePointDistance(&quad->plane, &edgeEndpoint);
|
||||||
|
|
||||||
|
if (edgeDistance > NEGATIVE_PENETRATION_BIAS) {
|
||||||
|
return edgesToCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
int otherEdgesToCheck = collisionQuadDetermineEdges(&edgeEndpoint, quad);
|
||||||
|
|
||||||
|
if (!otherEdgesToCheck) {
|
||||||
|
if (output->contactCount == 0) {
|
||||||
|
collisionQuadInitializeNormalContact(quad, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ContactState* contact = &output->contacts[output->contactCount];
|
||||||
|
|
||||||
|
++output->contactCount;
|
||||||
|
|
||||||
|
vector3Sub(&edgeEndpoint, &cylinderTransform->position, &contact->rb);
|
||||||
|
vector3AddScaled(&edgeEndpoint, &quad->plane.normal, -edgeDistance, &contact->ra);
|
||||||
|
|
||||||
|
contact->id = 1;
|
||||||
|
contact->penetration = edgeDistance;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return edgesToCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
int collisionCylinderCollideQuad(void* data, struct Transform* cylinderTransform, struct CollisionQuad* quad, struct ContactConstraintState* output) {
|
||||||
|
struct Vector3 centerAxis;
|
||||||
|
quatMultVector(&cylinderTransform->rotation, &gUp, ¢erAxis);
|
||||||
|
|
||||||
|
float normalDotProduct = vector3Dot(¢erAxis, &quad->plane.normal);
|
||||||
|
|
||||||
|
struct Vector3 capCenterTowardsPlane;
|
||||||
|
vector3AddScaled(&quad->plane.normal, ¢erAxis, -normalDotProduct, &capCenterTowardsPlane);
|
||||||
|
|
||||||
|
float magSqrd = vector3MagSqrd(&capCenterTowardsPlane);
|
||||||
|
|
||||||
|
int edgesToCheck;
|
||||||
|
|
||||||
|
struct CollisionCylinder* cylinder = (struct CollisionCylinder*)data;
|
||||||
|
|
||||||
|
if (fabsf(magSqrd) > 0.7f) {
|
||||||
|
// TODO treat as upright
|
||||||
|
edgesToCheck = 0;
|
||||||
|
} else {
|
||||||
|
vector3Scale(&capCenterTowardsPlane, &capCenterTowardsPlane, 1.0f / sqrtf(magSqrd));
|
||||||
|
edgesToCheck = _collisionCylinderParallel(cylinder, cylinderTransform, ¢erAxis, &capCenterTowardsPlane, normalDotProduct, quad, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!edgesToCheck) {
|
||||||
|
return output->contactCount > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO check edges and points of quad
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
14
src/physics/collision_cylinder.h
Normal file
14
src/physics/collision_cylinder.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef __COLLISION_CYLINDER_H__
|
||||||
|
#define __COLLISION_CYLINDER_H__
|
||||||
|
|
||||||
|
#include "collision_quad.h"
|
||||||
|
|
||||||
|
struct CollisionCylinder {
|
||||||
|
float radius;
|
||||||
|
float halfHeight;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int collisionCylinderCollideQuad(void* data, struct Transform* cylinderTransform, struct CollisionQuad* quad, struct ContactConstraintState* output);
|
||||||
|
|
||||||
|
#endif
|
|
@ -8,6 +8,15 @@
|
||||||
|
|
||||||
#define POINT_NO_OVERLAP -1
|
#define POINT_NO_OVERLAP -1
|
||||||
|
|
||||||
|
void collisionQuadInitializeNormalContact(struct CollisionQuad* quad, struct ContactConstraintState* output) {
|
||||||
|
output->normal = quad->plane.normal;
|
||||||
|
output->tangentVectors[0] = quad->edgeA;
|
||||||
|
output->tangentVectors[1] = quad->edgeB;
|
||||||
|
|
||||||
|
output->restitution = 0.0f;
|
||||||
|
output->friction = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* -------
|
* -------
|
||||||
* | 3 |
|
* | 3 |
|
||||||
|
@ -351,7 +360,7 @@ int collisionBoxCollideQuad(void* data, struct Transform* boxTransform, struct C
|
||||||
|
|
||||||
output->contactCount = 0;
|
output->contactCount = 0;
|
||||||
output->normal = quad->plane.normal;
|
output->normal = quad->plane.normal;
|
||||||
// TODO actually calculate tangent
|
// TODO handle non orthogonal edges
|
||||||
output->tangentVectors[0] = quad->edgeA;
|
output->tangentVectors[0] = quad->edgeA;
|
||||||
output->tangentVectors[1] = quad->edgeB;
|
output->tangentVectors[1] = quad->edgeB;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ struct CollisionQuad {
|
||||||
u8 enabledEdges;
|
u8 enabledEdges;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void collisionQuadInitializeNormalContact(struct CollisionQuad* quad, struct ContactConstraintState* output);
|
||||||
int collisionQuadDetermineEdges(struct Vector3* worldPoint, struct CollisionQuad* quad);
|
int collisionQuadDetermineEdges(struct Vector3* worldPoint, struct CollisionQuad* quad);
|
||||||
int collisionBoxCollideQuad(void* data, struct Transform* boxTransform, struct CollisionQuad* quad, struct ContactConstraintState* output);
|
int collisionBoxCollideQuad(void* data, struct Transform* boxTransform, struct CollisionQuad* quad, struct ContactConstraintState* output);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue