mirror of
https://github.com/bulletphysics/bullet3
synced 2024-12-14 05:40:05 +00:00
134 lines
3.8 KiB
C++
134 lines
3.8 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
|
|
#include "raytri.h"
|
|
|
|
/*----------------------------------------------------------------------
|
|
Copyright (c) 2004 Open Dynamics Framework Group
|
|
www.physicstools.org
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided
|
|
that the following conditions are met:
|
|
|
|
Redistributions of source code must retain the above copyright notice, this list of conditions
|
|
and the following disclaimer.
|
|
|
|
Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
|
|
Neither the name of the Open Dynamics Framework Group nor the names of its contributors may
|
|
be used to endorse or promote products derived from this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
DISCLAIMED. IN NO EVENT SHALL THE INTEL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
|
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
-----------------------------------------------------------------------*/
|
|
|
|
// http://codesuppository.blogspot.com
|
|
//
|
|
// mailto: jratcliff@infiniplex.net
|
|
//
|
|
// http://www.amillionpixels.us
|
|
//
|
|
|
|
|
|
/* a = b - c */
|
|
#define vector(a,b,c) \
|
|
(a)[0] = (b)[0] - (c)[0]; \
|
|
(a)[1] = (b)[1] - (c)[1]; \
|
|
(a)[2] = (b)[2] - (c)[2];
|
|
|
|
|
|
|
|
#define innerProduct(v,q) \
|
|
((v)[0] * (q)[0] + \
|
|
(v)[1] * (q)[1] + \
|
|
(v)[2] * (q)[2])
|
|
|
|
#define crossProduct(a,b,c) \
|
|
(a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \
|
|
(a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \
|
|
(a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1];
|
|
|
|
bool rayIntersectsTriangle(const float *p,const float *d,const float *v0,const float *v1,const float *v2,float &t)
|
|
{
|
|
|
|
float e1[3],e2[3],h[3],s[3],q[3];
|
|
float a,f,u,v;
|
|
|
|
vector(e1,v1,v0);
|
|
vector(e2,v2,v0);
|
|
crossProduct(h,d,e2);
|
|
a = innerProduct(e1,h);
|
|
|
|
if (a > -0.00001 && a < 0.00001)
|
|
return(false);
|
|
|
|
f = 1/a;
|
|
vector(s,p,v0);
|
|
u = f * (innerProduct(s,h));
|
|
|
|
if (u < 0.0 || u > 1.0)
|
|
return(false);
|
|
|
|
crossProduct(q,s,e1);
|
|
v = f * innerProduct(d,q);
|
|
if (v < 0.0 || u + v > 1.0)
|
|
return(false);
|
|
// at this stage we can compute t to find out where
|
|
// the intersection point is on the line
|
|
t = f * innerProduct(e2,q);
|
|
if (t > 0) // ray intersection
|
|
return(true);
|
|
else // this means that there is a line intersection
|
|
// but not a ray intersection
|
|
return (false);
|
|
}
|
|
|
|
|
|
bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const float *p1,const float *p2,const float *p3,float *sect)
|
|
{
|
|
float dir[3];
|
|
|
|
dir[0] = rayEnd[0] - rayStart[0];
|
|
dir[1] = rayEnd[1] - rayStart[1];
|
|
dir[2] = rayEnd[2] - rayStart[2];
|
|
|
|
float d = sqrtf(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]);
|
|
float r = 1.0f / d;
|
|
|
|
dir[0]*=r;
|
|
dir[1]*=r;
|
|
dir[2]*=r;
|
|
|
|
|
|
float t;
|
|
|
|
bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t );
|
|
|
|
if ( ret )
|
|
{
|
|
if ( t > d )
|
|
{
|
|
sect[0] = rayStart[0] + dir[0]*t;
|
|
sect[1] = rayStart[1] + dir[1]*t;
|
|
sect[2] = rayStart[2] + dir[2]*t;
|
|
}
|
|
else
|
|
{
|
|
ret = false;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|