| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #include "float_math.h"
- #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: [email protected]
- //
- // 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;
- }
|