mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-23 13:46:24 +00:00
First Commit
For Azeroth!
This commit is contained in:
186
dep/g3dlite/source/Triangle.cpp
Normal file
186
dep/g3dlite/source/Triangle.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/**
|
||||
@file Triangle.cpp
|
||||
|
||||
@maintainer Morgan McGuire, http://graphics.cs.williams.edu
|
||||
|
||||
@created 2001-04-06
|
||||
@edited 2008-12-28
|
||||
|
||||
Copyright 2000-2009, Morgan McGuire.
|
||||
All rights reserved.
|
||||
*/
|
||||
|
||||
#include "G3D/platform.h"
|
||||
#include "G3D/Triangle.h"
|
||||
#include "G3D/Plane.h"
|
||||
#include "G3D/BinaryInput.h"
|
||||
#include "G3D/BinaryOutput.h"
|
||||
#include "G3D/debugAssert.h"
|
||||
#include "G3D/AABox.h"
|
||||
#include "G3D/Ray.h"
|
||||
|
||||
namespace G3D {
|
||||
|
||||
|
||||
void Triangle::init(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
|
||||
|
||||
_plane = Plane(v0, v1, v2);
|
||||
_vertex[0] = v0;
|
||||
_vertex[1] = v1;
|
||||
_vertex[2] = v2;
|
||||
|
||||
static int next[] = {1,2,0};
|
||||
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
const Vector3& e = _vertex[next[i]] - _vertex[i];
|
||||
edgeMagnitude[i] = e.magnitude();
|
||||
|
||||
if (edgeMagnitude[i] == 0) {
|
||||
edgeDirection[i] = Vector3::zero();
|
||||
} else {
|
||||
edgeDirection[i] = e / (float)edgeMagnitude[i];
|
||||
}
|
||||
}
|
||||
|
||||
_edge01 = _vertex[1] - _vertex[0];
|
||||
_edge02 = _vertex[2] - _vertex[0];
|
||||
|
||||
_primaryAxis = _plane.normal().primaryAxis();
|
||||
_area = 0.5f * edgeDirection[0].cross(edgeDirection[2]).magnitude() * (edgeMagnitude[0] * edgeMagnitude[2]);
|
||||
//0.5f * (_vertex[1] - _vertex[0]).cross(_vertex[2] - _vertex[0]).dot(_plane.normal());
|
||||
}
|
||||
|
||||
|
||||
Triangle::Triangle() {
|
||||
init(Vector3::zero(), Vector3::zero(), Vector3::zero());
|
||||
}
|
||||
|
||||
|
||||
Triangle::Triangle(const Vector3& v0, const Vector3& v1, const Vector3& v2) {
|
||||
init(v0, v1, v2);
|
||||
}
|
||||
|
||||
|
||||
Triangle::~Triangle() {
|
||||
}
|
||||
|
||||
|
||||
Triangle::Triangle(class BinaryInput& b) {
|
||||
deserialize(b);
|
||||
}
|
||||
|
||||
|
||||
void Triangle::serialize(class BinaryOutput& b) {
|
||||
_vertex[0].serialize(b);
|
||||
_vertex[1].serialize(b);
|
||||
_vertex[2].serialize(b);
|
||||
}
|
||||
|
||||
|
||||
void Triangle::deserialize(class BinaryInput& b) {
|
||||
_vertex[0].deserialize(b);
|
||||
_vertex[1].deserialize(b);
|
||||
_vertex[2].deserialize(b);
|
||||
init(_vertex[0], _vertex[1], _vertex[2]);
|
||||
}
|
||||
|
||||
|
||||
float Triangle::area() const {
|
||||
return _area;
|
||||
}
|
||||
|
||||
|
||||
const Vector3& Triangle::normal() const {
|
||||
return _plane.normal();
|
||||
}
|
||||
|
||||
|
||||
const Plane& Triangle::plane() const {
|
||||
return _plane;
|
||||
}
|
||||
|
||||
|
||||
Vector3 Triangle::center() const {
|
||||
return (_vertex[0] + _vertex[1] + _vertex[2]) / 3.0;
|
||||
}
|
||||
|
||||
Vector3 Triangle::randomPoint() const {
|
||||
// Choose a random point in the parallelogram
|
||||
|
||||
float s = uniformRandom();
|
||||
float t = uniformRandom();
|
||||
|
||||
if (t > 1.0f - s) {
|
||||
// Outside the triangle; reflect about the
|
||||
// diagonal of the parallelogram
|
||||
t = 1.0f - t;
|
||||
s = 1.0f - s;
|
||||
}
|
||||
|
||||
return _edge01 * s + _edge02 * t + _vertex[0];
|
||||
}
|
||||
|
||||
|
||||
void Triangle::getBounds(AABox& out) const {
|
||||
Vector3 lo = _vertex[0];
|
||||
Vector3 hi = lo;
|
||||
|
||||
for (int i = 1; i < 3; ++i) {
|
||||
lo = lo.min(_vertex[i]);
|
||||
hi = hi.max(_vertex[i]);
|
||||
}
|
||||
|
||||
out = AABox(lo, hi);
|
||||
}
|
||||
|
||||
|
||||
bool Triangle::intersect(const Ray& ray, float& distance, float baryCoord[3]) const {
|
||||
static const float EPS = 1e-5f;
|
||||
|
||||
// See RTR2 ch. 13.7 for the algorithm.
|
||||
|
||||
const Vector3& e1 = edge01();
|
||||
const Vector3& e2 = edge02();
|
||||
const Vector3 p(ray.direction().cross(e2));
|
||||
const float a = e1.dot(p);
|
||||
|
||||
if (abs(a) < EPS) {
|
||||
// Determinant is ill-conditioned; abort early
|
||||
return false;
|
||||
}
|
||||
|
||||
const float f = 1.0f / a;
|
||||
const Vector3 s(ray.origin() - vertex(0));
|
||||
const float u = f * s.dot(p);
|
||||
|
||||
if ((u < 0.0f) || (u > 1.0f)) {
|
||||
// We hit the plane of the m_geometry, but outside the m_geometry
|
||||
return false;
|
||||
}
|
||||
|
||||
const Vector3 q(s.cross(e1));
|
||||
const float v = f * ray.direction().dot(q);
|
||||
|
||||
if ((v < 0.0f) || ((u + v) > 1.0f)) {
|
||||
// We hit the plane of the triangle, but outside the triangle
|
||||
return false;
|
||||
}
|
||||
|
||||
const float t = f * e2.dot(q);
|
||||
|
||||
if ((t > 0.0f) && (t < distance)) {
|
||||
// This is a new hit, closer than the previous one
|
||||
distance = t;
|
||||
|
||||
baryCoord[0] = 1.0 - u - v;
|
||||
baryCoord[1] = u;
|
||||
baryCoord[2] = v;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// This hit is after the previous hit, so ignore it
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // G3D
|
||||
Reference in New Issue
Block a user