Lattest PR review
Function names, code formatting...
This commit is contained in:
parent
0369bb4c8c
commit
658c280669
@ -203,7 +203,6 @@ EXAMPLES = \
|
||||
core_gestures_detection \
|
||||
core_3d_mode \
|
||||
core_3d_picking \
|
||||
core_3d_raypick \
|
||||
core_3d_camera_free \
|
||||
core_3d_camera_first_person \
|
||||
core_2d_camera \
|
||||
@ -237,6 +236,7 @@ EXAMPLES = \
|
||||
models_obj_loading \
|
||||
models_heightmap \
|
||||
models_cubicmap \
|
||||
models_ray_picking \
|
||||
shaders_model_shader \
|
||||
shaders_shapes_textures \
|
||||
shaders_custom_uniform \
|
||||
@ -321,11 +321,6 @@ core_3d_mode: core_3d_mode.c
|
||||
core_3d_picking: core_3d_picking.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - 3d ray picking
|
||||
core_3d_raypick: core_3d_raypick.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
|
||||
# compile [core] example - 3d camera free
|
||||
core_3d_camera_free: core_3d_camera_free.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
@ -462,6 +457,10 @@ models_heightmap: models_heightmap.c
|
||||
models_cubicmap: models_cubicmap.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [models] example - model ray picking
|
||||
models_ray_picking: models_ray_picking.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [shaders] example - model shader
|
||||
shaders_model_shader: shaders_model_shader.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [core] example - Ray-Picking in 3d mode, ground plane, triangle, mesh
|
||||
* raylib [models] example - Ray picking in 3d mode, ground plane, triangle, mesh
|
||||
*
|
||||
* This example has been created using raylib 1.3 (www.raylib.com)
|
||||
* This example has been created using raylib 1.7 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
|
||||
@ -11,7 +11,7 @@
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
#include "../src/raymath.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <float.h>
|
||||
@ -24,7 +24,7 @@ int main()
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d ray picking");
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - 3d ray picking");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera;
|
||||
@ -41,22 +41,22 @@ int main()
|
||||
Model tower = LoadModel("resources/model/lowpoly-tower.obj"); // Load OBJ model
|
||||
Texture2D texture = LoadTexture("resources/model/lowpoly-tower.png"); // Load model texture
|
||||
tower.material.texDiffuse = texture; // Set model diffuse texture
|
||||
|
||||
Vector3 towerPos = { 0.0f, 0.0f, 0.0f }; // Set model position
|
||||
BoundingBox towerBBox = CalculateBoundingBox( tower.mesh );
|
||||
bool hitMeshBBox;
|
||||
bool hitTriangle;
|
||||
bool hitMeshBBox = false;
|
||||
bool hitTriangle = false;
|
||||
|
||||
// Test triangle
|
||||
Vector3 ta = (Vector3){ -25.0, 0.5, 0.0 };
|
||||
Vector3 tb = (Vector3){ -4.0, 2.5, 1.0 };
|
||||
Vector3 tc = (Vector3){ -8.0, 6.5, 0.0 };
|
||||
|
||||
Vector3 bary = {0};
|
||||
Vector3 bary = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
@ -65,7 +65,6 @@ int main()
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateCamera(&camera); // Update camera
|
||||
|
||||
|
||||
// Display information about closest hit
|
||||
RayHitInfo nearestHit;
|
||||
char *hitObjectName = "None";
|
||||
@ -76,41 +75,50 @@ int main()
|
||||
// Get ray and test against ground, triangle, and mesh
|
||||
ray = GetMouseRay(GetMousePosition(), camera);
|
||||
|
||||
RayHitInfo groundHitInfo = RaycastGroundPlane( ray, 0.0 );
|
||||
if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance)) {
|
||||
// Check ray collision aginst ground plane
|
||||
RayHitInfo groundHitInfo = GetCollisionRayGround(ray, 0.0f);
|
||||
|
||||
if ((groundHitInfo.hit) && (groundHitInfo.distance < nearestHit.distance))
|
||||
{
|
||||
nearestHit = groundHitInfo;
|
||||
cursorColor = GREEN;
|
||||
hitObjectName = "Ground";
|
||||
}
|
||||
|
||||
RayHitInfo triHitInfo = RaycastTriangle( ray, ta, tb, tc );
|
||||
if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance)) {
|
||||
// Check ray collision against test triangle
|
||||
RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, ta, tb, tc);
|
||||
|
||||
if ((triHitInfo.hit) && (triHitInfo.distance < nearestHit.distance))
|
||||
{
|
||||
nearestHit = triHitInfo;
|
||||
cursorColor = PURPLE;
|
||||
hitObjectName = "Triangle";
|
||||
|
||||
bary = Barycentric( nearestHit.hitPosition, ta, tb, tc );
|
||||
bary = Barycenter(nearestHit.hitPosition, ta, tb, tc);
|
||||
hitTriangle = true;
|
||||
} else {
|
||||
hitTriangle = false;
|
||||
}
|
||||
}
|
||||
else hitTriangle = false;
|
||||
|
||||
RayHitInfo meshHitInfo;
|
||||
|
||||
// check the bounding box first, before trying the full ray/mesh test
|
||||
if (CheckCollisionRayBox( ray, towerBBox )) {
|
||||
// Check ray collision against bounding box first, before trying the full ray-mesh test
|
||||
if (CheckCollisionRayBox(ray, towerBBox))
|
||||
{
|
||||
hitMeshBBox = true;
|
||||
meshHitInfo = RaycastMesh( ray, &tower.mesh );
|
||||
if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance)) {
|
||||
|
||||
// Check ray collision against mesh
|
||||
meshHitInfo = GetCollisionRayMesh(ray, &tower.mesh);
|
||||
|
||||
if ((meshHitInfo.hit) && (meshHitInfo.distance < nearestHit.distance))
|
||||
{
|
||||
nearestHit = meshHitInfo;
|
||||
cursorColor = ORANGE;
|
||||
hitObjectName = "Mesh";
|
||||
}
|
||||
} else {
|
||||
hitMeshBBox = false;
|
||||
}
|
||||
|
||||
|
||||
} hitMeshBBox = false;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
@ -120,65 +128,59 @@ int main()
|
||||
Begin3dMode(camera);
|
||||
|
||||
// Draw the tower
|
||||
DrawModel( tower, towerPos, 1.0, WHITE );
|
||||
DrawModel(tower, towerPos, 1.0, WHITE);
|
||||
|
||||
// Draw the test triangle
|
||||
DrawLine3D( ta, tb, PURPLE );
|
||||
DrawLine3D( tb, tc, PURPLE );
|
||||
DrawLine3D( tc, ta, PURPLE );
|
||||
DrawLine3D(ta, tb, PURPLE);
|
||||
DrawLine3D(tb, tc, PURPLE);
|
||||
DrawLine3D(tc, ta, PURPLE);
|
||||
|
||||
// Draw the mesh bbox if we hit it
|
||||
if (hitMeshBBox) {
|
||||
DrawBoundingBox( towerBBox, LIME );
|
||||
}
|
||||
if (hitMeshBBox) DrawBoundingBox(towerBBox, LIME);
|
||||
|
||||
// If we hit something, draw the cursor at the hit point
|
||||
if (nearestHit.hit) {
|
||||
DrawCube( nearestHit.hitPosition, 0.5, 0.5, 0.5, cursorColor );
|
||||
DrawCubeWires( nearestHit.hitPosition, 0.5, 0.5, 0.5, YELLOW );
|
||||
if (nearestHit.hit)
|
||||
{
|
||||
DrawCube(nearestHit.hitPosition, 0.5, 0.5, 0.5, cursorColor);
|
||||
DrawCubeWires(nearestHit.hitPosition, 0.5, 0.5, 0.5, YELLOW);
|
||||
|
||||
Vector3 normalEnd;
|
||||
normalEnd.x = nearestHit.hitPosition.x + nearestHit.hitNormal.x;
|
||||
normalEnd.y = nearestHit.hitPosition.y + nearestHit.hitNormal.y;
|
||||
normalEnd.z = nearestHit.hitPosition.z + nearestHit.hitNormal.z;
|
||||
DrawLine3D( nearestHit.hitPosition, normalEnd, YELLOW );
|
||||
|
||||
DrawLine3D(nearestHit.hitPosition, normalEnd, YELLOW);
|
||||
}
|
||||
|
||||
DrawRay(ray, MAROON);
|
||||
|
||||
DrawGrid(10, 1.0f);
|
||||
DrawGrid(100, 1.0f);
|
||||
|
||||
End3dMode();
|
||||
|
||||
// Show some debug text
|
||||
char line[1024];
|
||||
sprintf( line, "Hit Object: %s\n", hitObjectName );
|
||||
DrawText( line, 10, 30, 15, BLACK );
|
||||
// Draw some debug GUI text
|
||||
DrawText(FormatText("Hit Object: %s", hitObjectName), 10, 50, 10, BLACK);
|
||||
|
||||
if (nearestHit.hit) {
|
||||
int ypos = 45;
|
||||
sprintf( line, "Distance: %3.2f", nearestHit.distance );
|
||||
DrawText( line, 10, ypos, 15, BLACK );
|
||||
ypos += 15;
|
||||
if (nearestHit.hit)
|
||||
{
|
||||
int ypos = 70;
|
||||
|
||||
sprintf( line, "Hit Pos: %3.2f %3.2f %3.2f",
|
||||
nearestHit.hitPosition.x, nearestHit.hitPosition.y, nearestHit.hitPosition.z );
|
||||
DrawText( line, 10, ypos, 15, BLACK );
|
||||
ypos += 15;
|
||||
DrawText(FormatText("Distance: %3.2f", nearestHit.distance), 10, ypos, 10, BLACK);
|
||||
|
||||
DrawText(FormatText("Hit Pos: %3.2f %3.2f %3.2f",
|
||||
nearestHit.hitPosition.x,
|
||||
nearestHit.hitPosition.y,
|
||||
nearestHit.hitPosition.z), 10, ypos + 15, 10, BLACK);
|
||||
|
||||
DrawText(FormatText("Hit Norm: %3.2f %3.2f %3.2f",
|
||||
nearestHit.hitNormal.x,
|
||||
nearestHit.hitNormal.y,
|
||||
nearestHit.hitNormal.z), 10, ypos + 30, 10, BLACK);
|
||||
|
||||
sprintf( line, "Hit Norm: %3.2f %3.2f %3.2f",
|
||||
nearestHit.hitNormal.x, nearestHit.hitNormal.y, nearestHit.hitNormal.z );
|
||||
DrawText( line, 10, ypos, 15, BLACK );
|
||||
ypos += 15;
|
||||
|
||||
if (hitTriangle) {
|
||||
sprintf( line, "Barycentric: %3.2f %3.2f %3.2f",
|
||||
bary.x, bary.y, bary.z );
|
||||
DrawText( line, 10, ypos, 15, BLACK );
|
||||
}
|
||||
if (hitTriangle) DrawText(FormatText("Barycenter: %3.2f %3.2f %3.2f", bary.x, bary.y, bary.z), 10, ypos + 45, 10, BLACK);
|
||||
}
|
||||
|
||||
DrawText( "Use Mouse to Move Camera", 10, 420, 15, LIGHTGRAY );
|
||||
DrawText("Use Mouse to Move Camera", 10, 430, 10, GRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
167
src/models.c
167
src/models.c
@ -1474,6 +1474,135 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box)
|
||||
return collision;
|
||||
}
|
||||
|
||||
// Get collision info between ray and mesh
|
||||
RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh)
|
||||
{
|
||||
RayHitInfo result = { 0 };
|
||||
|
||||
// If mesh doesn't have vertex data on CPU, can't test it.
|
||||
if (!mesh->vertices) return result;
|
||||
|
||||
// mesh->triangleCount may not be set, vertexCount is more reliable
|
||||
int triangleCount = mesh->vertexCount/3;
|
||||
|
||||
// Test against all triangles in mesh
|
||||
for (int i = 0; i < triangleCount; i++)
|
||||
{
|
||||
Vector3 a, b, c;
|
||||
Vector3 *vertdata = (Vector3 *)mesh->vertices;
|
||||
|
||||
if (mesh->indices)
|
||||
{
|
||||
a = vertdata[mesh->indices[i*3 + 0]];
|
||||
b = vertdata[mesh->indices[i*3 + 1]];
|
||||
c = vertdata[mesh->indices[i*3 + 2]];
|
||||
}
|
||||
else
|
||||
{
|
||||
a = vertdata[i*3 + 0];
|
||||
b = vertdata[i*3 + 1];
|
||||
c = vertdata[i*3 + 2];
|
||||
}
|
||||
|
||||
RayHitInfo triHitInfo = GetCollisionRayTriangle(ray, a, b, c);
|
||||
|
||||
if (triHitInfo.hit)
|
||||
{
|
||||
// Save the closest hit triangle
|
||||
if ((!result.hit) || (result.distance > triHitInfo.distance)) result = triHitInfo;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get collision info between ray and triangle
|
||||
// NOTE: Based on https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
|
||||
RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3)
|
||||
{
|
||||
#define EPSILON 0.000001 // A small number
|
||||
|
||||
Vector3 edge1, edge2;
|
||||
Vector3 p, q, tv;
|
||||
float det, invDet, u, v, t;
|
||||
RayHitInfo result = {0};
|
||||
|
||||
// Find vectors for two edges sharing V1
|
||||
edge1 = VectorSubtract(p2, p1);
|
||||
edge2 = VectorSubtract(p3, p1);
|
||||
|
||||
// Begin calculating determinant - also used to calculate u parameter
|
||||
p = VectorCrossProduct(ray.direction, edge2);
|
||||
|
||||
// If determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle
|
||||
det = VectorDotProduct(edge1, p);
|
||||
|
||||
// Avoid culling!
|
||||
if ((det > -EPSILON) && (det < EPSILON)) return result;
|
||||
|
||||
invDet = 1.0f/det;
|
||||
|
||||
// Calculate distance from V1 to ray origin
|
||||
tv = VectorSubtract(ray.position, p1);
|
||||
|
||||
// Calculate u parameter and test bound
|
||||
u = VectorDotProduct(tv, p)*invDet;
|
||||
|
||||
// The intersection lies outside of the triangle
|
||||
if ((u < 0.0f) || (u > 1.0f)) return result;
|
||||
|
||||
// Prepare to test v parameter
|
||||
q = VectorCrossProduct(tv, edge1);
|
||||
|
||||
// Calculate V parameter and test bound
|
||||
v = VectorDotProduct(ray.direction, q)*invDet;
|
||||
|
||||
// The intersection lies outside of the triangle
|
||||
if ((v < 0.0f) || ((u + v) > 1.0f)) return result;
|
||||
|
||||
t = VectorDotProduct(edge2, q)*invDet;
|
||||
|
||||
if (t > EPSILON)
|
||||
{
|
||||
// Ray hit, get hit point and normal
|
||||
result.hit = true;
|
||||
result.distance = t;
|
||||
result.hit = true;
|
||||
result.hitNormal = VectorCrossProduct(edge1, edge2);
|
||||
VectorNormalize(&result.hitNormal);
|
||||
Vector3 rayDir = ray.direction;
|
||||
VectorScale(&rayDir, t);
|
||||
result.hitPosition = VectorAdd(ray.position, rayDir);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get collision info between ray and ground plane (Y-normal plane)
|
||||
RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight)
|
||||
{
|
||||
#define EPSILON 0.000001 // A small number
|
||||
|
||||
RayHitInfo result = { 0 };
|
||||
|
||||
if (fabsf(ray.direction.y) > EPSILON)
|
||||
{
|
||||
float t = (ray.position.y - groundHeight)/-ray.direction.y;
|
||||
|
||||
if (t >= 0.0)
|
||||
{
|
||||
Vector3 rayDir = ray.direction;
|
||||
VectorScale(&rayDir, t);
|
||||
result.hit = true;
|
||||
result.distance = t;
|
||||
result.hitNormal = (Vector3){ 0.0, 1.0, 0.0 };
|
||||
result.hitPosition = VectorAdd(ray.position, rayDir);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculate mesh bounding box limits
|
||||
// NOTE: minVertex and maxVertex should be transformed by model transform matrix (position, scale, rotate)
|
||||
BoundingBox CalculateBoundingBox(Mesh mesh)
|
||||
@ -1918,41 +2047,3 @@ static Material LoadMTL(const char *fileName)
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
RayHitInfo RaycastMesh( Ray ray, Mesh *mesh )
|
||||
{
|
||||
RayHitInfo result = {0};
|
||||
|
||||
// If mesh doesn't have vertex data on CPU, can't test it.
|
||||
if (!mesh->vertices) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// mesh->triangleCount may not be set, vertexCount is more reliable
|
||||
int triangleCount = mesh->vertexCount / 3;
|
||||
|
||||
// Test against all triangles in mesh
|
||||
for (int i=0; i < triangleCount; i++) {
|
||||
Vector3 a, b, c;
|
||||
Vector3 *vertdata = (Vector3*)mesh->vertices;
|
||||
if (mesh->indices) {
|
||||
a = vertdata[ mesh->indices[i*3+0] ];
|
||||
b = vertdata[ mesh->indices[i*3+1] ];
|
||||
c = vertdata[ mesh->indices[i*3+2] ];
|
||||
} else {
|
||||
a = vertdata[i*3+0];
|
||||
b = vertdata[i*3+1];
|
||||
c = vertdata[i*3+2];
|
||||
}
|
||||
|
||||
RayHitInfo triHitInfo = RaycastTriangle( ray, a, b, c );
|
||||
if (triHitInfo.hit) {
|
||||
// Save the closest hit triangle
|
||||
if ((!result.hit)||(result.distance > triHitInfo.distance)) {
|
||||
result = triHitInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
21
src/raylib.h
21
src/raylib.h
@ -97,9 +97,6 @@
|
||||
#define DEG2RAD (PI/180.0f)
|
||||
#define RAD2DEG (180.0f/PI)
|
||||
|
||||
// A small number
|
||||
#define EPSILON 0.000001
|
||||
|
||||
// raylib Config Flags
|
||||
#define FLAG_FULLSCREEN_MODE 1
|
||||
#define FLAG_RESIZABLE_WINDOW 2
|
||||
@ -496,10 +493,10 @@ typedef struct Ray {
|
||||
|
||||
// Information returned from a raycast
|
||||
typedef struct RayHitInfo {
|
||||
bool hit; // Did the ray hit something?
|
||||
float distance; // Distance to nearest hit
|
||||
Vector3 hitPosition; // Position of nearest hit
|
||||
Vector3 hitNormal; // Surface normal of hit
|
||||
bool hit; // Did the ray hit something?
|
||||
float distance; // Distance to nearest hit
|
||||
Vector3 hitPosition; // Position of nearest hit
|
||||
Vector3 hitNormal; // Surface normal of hit
|
||||
} RayHitInfo;
|
||||
|
||||
// Wave type, defines audio wave data
|
||||
@ -920,13 +917,9 @@ RLAPI bool CheckCollisionRaySphere(Ray ray, Vector3 spherePosition, float sphere
|
||||
RLAPI bool CheckCollisionRaySphereEx(Ray ray, Vector3 spherePosition, float sphereRadius,
|
||||
Vector3 *collisionPoint); // Detect collision between ray and sphere, returns collision point
|
||||
RLAPI bool CheckCollisionRayBox(Ray ray, BoundingBox box); // Detect collision between ray and box
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Ray Casts
|
||||
//------------------------------------------------------------------------------------
|
||||
RLAPI RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight );
|
||||
RLAPI RayHitInfo RaycastTriangle( Ray ray, Vector3 a, Vector3 b, Vector3 c );
|
||||
RLAPI RayHitInfo RaycastMesh( Ray ray, Mesh *mesh );
|
||||
RLAPI RayHitInfo GetCollisionRayMesh(Ray ray, Mesh *mesh); // Get collision info between ray and mesh
|
||||
RLAPI RayHitInfo GetCollisionRayTriangle(Ray ray, Vector3 p1, Vector3 p2, Vector3 p3); // Get collision info between ray and triangle
|
||||
RLAPI RayHitInfo GetCollisionRayGround(Ray ray, float groundHeight); // Get collision info between ray and ground plane (Y-normal plane)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Shaders System Functions (Module: rlgl)
|
||||
|
@ -130,7 +130,7 @@ RMDEF void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Ve
|
||||
RMDEF Vector3 VectorZero(void); // Return a Vector3 init to zero
|
||||
RMDEF Vector3 VectorMin(Vector3 vec1, Vector3 vec2); // Return min value for each pair of components
|
||||
RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2); // Return max value for each pair of components
|
||||
RMDEF Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Barycentric coords for p in triangle abc
|
||||
RMDEF Vector3 Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c); // Barycenter coords for p in triangle abc
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration to work with Matrix
|
||||
@ -383,26 +383,27 @@ RMDEF Vector3 VectorMax(Vector3 vec1, Vector3 vec2)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Compute barycentric coordinates (u, v, w) for
|
||||
// point p with respect to triangle (a, b, c)
|
||||
// Assumes P is on the plane of the triangle
|
||||
RMDEF Vector3 Barycentric(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
|
||||
// Compute barycenter coordinates (u, v, w) for point p with respect to triangle (a, b, c)
|
||||
// NOTE: Assumes P is on the plane of the triangle
|
||||
RMDEF Vector3 Barycenter(Vector3 p, Vector3 a, Vector3 b, Vector3 c)
|
||||
{
|
||||
|
||||
//Vector v0 = b - a, v1 = c - a, v2 = p - a;
|
||||
Vector3 v0 = VectorSubtract( b, a );
|
||||
Vector3 v1 = VectorSubtract( c, a );
|
||||
Vector3 v2 = VectorSubtract( p, a );
|
||||
|
||||
Vector3 v0 = VectorSubtract(b, a);
|
||||
Vector3 v1 = VectorSubtract(c, a);
|
||||
Vector3 v2 = VectorSubtract(p, a);
|
||||
float d00 = VectorDotProduct(v0, v0);
|
||||
float d01 = VectorDotProduct(v0, v1);
|
||||
float d11 = VectorDotProduct(v1, v1);
|
||||
float d20 = VectorDotProduct(v2, v0);
|
||||
float d21 = VectorDotProduct(v2, v1);
|
||||
float denom = d00 * d11 - d01 * d01;
|
||||
|
||||
float denom = d00*d11 - d01*d01;
|
||||
|
||||
Vector3 result;
|
||||
result.y = (d11 * d20 - d01 * d21) / denom;
|
||||
result.z = (d00 * d21 - d01 * d20) / denom;
|
||||
|
||||
result.y = (d11*d20 - d01*d21)/denom;
|
||||
result.z = (d00*d21 - d01*d20)/denom;
|
||||
result.x = 1.0f - (result.z + result.y);
|
||||
|
||||
return result;
|
||||
|
81
src/shapes.c
81
src/shapes.c
@ -534,84 +534,3 @@ Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2)
|
||||
|
||||
return retRec;
|
||||
}
|
||||
|
||||
|
||||
RayHitInfo RaycastGroundPlane( Ray ray, float groundHeight )
|
||||
{
|
||||
RayHitInfo result = {0};
|
||||
|
||||
if (fabs(ray.direction.y) > EPSILON)
|
||||
{
|
||||
float t = (ray.position.y - groundHeight) / -ray.direction.y;
|
||||
if (t >= 0.0) {
|
||||
Vector3 rayDir = ray.direction;
|
||||
VectorScale( &rayDir, t );
|
||||
result.hit = true;
|
||||
result.distance = t;
|
||||
result.hitNormal = (Vector3){ 0.0, 1.0, 0.0};
|
||||
result.hitPosition = VectorAdd( ray.position, rayDir );
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Adapted from:
|
||||
// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
|
||||
RayHitInfo RaycastTriangle( Ray ray, Vector3 a, Vector3 b, Vector3 c )
|
||||
{
|
||||
Vector3 e1, e2; //Edge1, Edge2
|
||||
Vector3 p, q, tv;
|
||||
float det, inv_det, u, v;
|
||||
float t;
|
||||
RayHitInfo result = {0};
|
||||
|
||||
//Find vectors for two edges sharing V1
|
||||
e1 = VectorSubtract( b, a);
|
||||
e2 = VectorSubtract( c, a);
|
||||
|
||||
//Begin calculating determinant - also used to calculate u parameter
|
||||
p = VectorCrossProduct( ray.direction, e2);
|
||||
|
||||
//if determinant is near zero, ray lies in plane of triangle or ray is parallel to plane of triangle
|
||||
det = VectorDotProduct(e1, p);
|
||||
|
||||
//NOT CULLING
|
||||
if(det > -EPSILON && det < EPSILON) return result;
|
||||
inv_det = 1.f / det;
|
||||
|
||||
//calculate distance from V1 to ray origin
|
||||
tv = VectorSubtract( ray.position, a );
|
||||
|
||||
//Calculate u parameter and test bound
|
||||
u = VectorDotProduct(tv, p) * inv_det;
|
||||
|
||||
//The intersection lies outside of the triangle
|
||||
if(u < 0.f || u > 1.f) return result;
|
||||
|
||||
//Prepare to test v parameter
|
||||
q = VectorCrossProduct( tv, e1 );
|
||||
|
||||
//Calculate V parameter and test bound
|
||||
v = VectorDotProduct( ray.direction, q) * inv_det;
|
||||
|
||||
//The intersection lies outside of the triangle
|
||||
if(v < 0.f || (u + v) > 1.f) return result;
|
||||
|
||||
t = VectorDotProduct(e2, q) * inv_det;
|
||||
|
||||
|
||||
if(t > EPSILON) {
|
||||
// ray hit, get hit point and normal
|
||||
result.hit = true;
|
||||
result.distance = t;
|
||||
|
||||
result.hit = true;
|
||||
result.hitNormal = VectorCrossProduct( e1, e2 );
|
||||
VectorNormalize( &result.hitNormal );
|
||||
Vector3 rayDir = ray.direction;
|
||||
VectorScale( &rayDir, t );
|
||||
result.hitPosition = VectorAdd( ray.position, rayDir );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user