Merge changes from internal branch.
- Add frustum class and bezier evaluation functions. - Add component accessors to vector. - Add matrix constructors. - Fix errors in sparse solvers. - Better robust orthogonalization. - Fix montecarlo distribution.pull/216/head
parent
e5ae0c0e20
commit
b4f17b968a
@ -0,0 +1,97 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#include "Bezier.h"
|
||||
|
||||
|
||||
using namespace nv;
|
||||
|
||||
|
||||
static void deCasteljau(float u, Vector3::Arg p0, Vector3::Arg p1, Vector3::Arg p2, Vector3::Arg p3, Vector3 * p)
|
||||
{
|
||||
Vector3 q0 = lerp(p0, p1, u);
|
||||
Vector3 q1 = lerp(p1, p2, u);
|
||||
Vector3 q2 = lerp(p2, p3, u);
|
||||
Vector3 r0 = lerp(q0, q1, u);
|
||||
Vector3 r1 = lerp(q1, q2, u);
|
||||
|
||||
*p = lerp(r0, r1, u);
|
||||
}
|
||||
|
||||
static void deCasteljau(float u, Vector3::Arg p0, Vector3::Arg p1, Vector3::Arg p2, Vector3::Arg p3, Vector3 * p, Vector3 * dp)
|
||||
{
|
||||
Vector3 q0 = lerp(p0, p1, u);
|
||||
Vector3 q1 = lerp(p1, p2, u);
|
||||
Vector3 q2 = lerp(p2, p3, u);
|
||||
Vector3 r0 = lerp(q0, q1, u);
|
||||
Vector3 r1 = lerp(q1, q2, u);
|
||||
|
||||
*dp = r0 - r1;
|
||||
*p = lerp(r0, r1, u);
|
||||
}
|
||||
|
||||
|
||||
void nv::evaluateCubicBezierPatch(float u, float v,
|
||||
Vector3::Arg p0, Vector3::Arg p1, Vector3::Arg p2, Vector3::Arg p3,
|
||||
Vector3::Arg p4, Vector3::Arg p5, Vector3::Arg p6, Vector3::Arg p7,
|
||||
Vector3::Arg p8, Vector3::Arg p9, Vector3::Arg pA, Vector3::Arg pB,
|
||||
Vector3::Arg pC, Vector3::Arg pD, Vector3::Arg pE, Vector3::Arg pF,
|
||||
Vector3 * pos, Vector3 * du, Vector3 * dv)
|
||||
{
|
||||
#if 0
|
||||
Vector2 L0(1-u,1-v);
|
||||
Vector2 L1(u,v);
|
||||
|
||||
Vector2 Q0 = L0 * L0;
|
||||
Vector2 Q1 = 2 * L0 * L1;
|
||||
Vector2 Q2 = L1 * L1;
|
||||
|
||||
Vector2 B0 = L0 * L0 * L0;
|
||||
Vector2 B1 = 3 * L0 * L0 * L1;
|
||||
Vector2 B2 = 3 * L1 * L1 * L0;
|
||||
Vector2 B3 = L1 * L1 * L1;
|
||||
|
||||
*pos =
|
||||
(B0.x() * p0 + B1.x() * p1 + B2.x() * p2 + B3.x() * p3) * B0.y() +
|
||||
(B0.x() * p4 + B1.x() * p5 + B2.x() * p6 + B3.x() * p7) * B1.y() +
|
||||
(B0.x() * p8 + B1.x() * p9 + B2.x() * pA + B3.x() * pB) * B2.y() +
|
||||
(B0.x() * pC + B1.x() * pD + B2.x() * pE + B3.x() * pF) * B3.y();
|
||||
|
||||
*du =
|
||||
((p0-p1) * B0.y() + (p4-p5) * B1.y() + (p8-p9) * B2.y() + (pC-pD) * B3.y()) * Q0.x() +
|
||||
((p1-p2) * B0.y() + (p5-p6) * B1.y() + (p9-pA) * B2.y() + (pD-pE) * B3.y()) * Q1.x() +
|
||||
((p2-p3) * B0.y() + (p6-p7) * B1.y() + (pA-pB) * B2.y() + (pE-pF) * B3.y()) * Q2.x();
|
||||
|
||||
*dv =
|
||||
((p0-p4) * B0.x() + (p1-p5) * B1.x() + (p2-p6) * B2.x() + (p3-p7) * B3.x()) * Q0.y() +
|
||||
((p4-p8) * B0.x() + (p5-p9) * B1.x() + (p6-pA) * B2.x() + (p7-pB) * B3.x()) * Q1.y() +
|
||||
((p8-pC) * B0.x() + (p9-pD) * B1.x() + (pA-pE) * B2.x() + (pB-pF) * B3.x()) * Q2.y();
|
||||
#else
|
||||
Vector3 t0, t1, t2, t3;
|
||||
Vector3 q0, q1, q2, q3;
|
||||
|
||||
deCasteljau(u, p0, p1, p2, p3, &q0, &t0);
|
||||
deCasteljau(u, p4, p5, p6, p7, &q1, &t1);
|
||||
deCasteljau(u, p8, p9, pA, pB, &q2, &t2);
|
||||
deCasteljau(u, pC, pD, pE, pF, &q3, &t3);
|
||||
|
||||
deCasteljau(v, q0, q1, q2, q3, pos, dv);
|
||||
deCasteljau(v, t0, t1, t2, t3, du);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void nv::degreeElevate(Vector3::Arg p0, Vector3::Arg p1, Vector3::Arg p2, Vector3::Arg p3,
|
||||
Vector3 * q0, Vector3 * q1, Vector3 * q2, Vector3 * q3, Vector3 * q4)
|
||||
{
|
||||
}
|
||||
|
||||
void nv::evaluateQuarticBezierTriangle(float u, float v,
|
||||
Vector3::Arg p0, Vector3::Arg p1, Vector3::Arg p2, Vector3::Arg p3, Vector3::Arg p4,
|
||||
Vector3::Arg p5, Vector3::Arg p6, Vector3::Arg p7, Vector3::Arg p8,
|
||||
Vector3::Arg p9, Vector3::Arg pA, Vector3::Arg pB,
|
||||
Vector3::Arg pC, Vector3::Arg pD,
|
||||
Vector3::Arg pE,
|
||||
Vector3 * pos, Vector3 * du, Vector3 * dv)
|
||||
{
|
||||
}
|
||||
|
@ -0,0 +1,33 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#ifndef NV_MATH_BEZIER_H
|
||||
#define NV_MATH_BEZIER_H
|
||||
|
||||
#include <nvmath/nvmath.h>
|
||||
#include <nvmath/Vector.h>
|
||||
|
||||
namespace nv
|
||||
{
|
||||
|
||||
void evaluateCubicBezierPatch(float u, float v,
|
||||
Vector3::Arg p0, Vector3::Arg p1, Vector3::Arg p2, Vector3::Arg p3,
|
||||
Vector3::Arg p4, Vector3::Arg p5, Vector3::Arg p6, Vector3::Arg p7,
|
||||
Vector3::Arg p8, Vector3::Arg p9, Vector3::Arg pA, Vector3::Arg pB,
|
||||
Vector3::Arg pC, Vector3::Arg pD, Vector3::Arg pE, Vector3::Arg pF,
|
||||
Vector3 * pos, Vector3 * du, Vector3 * dv);
|
||||
|
||||
void degreeElevate(Vector3::Arg p0, Vector3::Arg p1, Vector3::Arg p2, Vector3::Arg p3,
|
||||
Vector3 * q0, Vector3 * q1, Vector3 * q2, Vector3 * q3, Vector3 * q4);
|
||||
|
||||
void evaluateQuarticBezierTriangle(float u, float v,
|
||||
Vector3::Arg p0, Vector3::Arg p1, Vector3::Arg p2, Vector3::Arg p3, Vector3::Arg p4,
|
||||
Vector3::Arg p5, Vector3::Arg p6, Vector3::Arg p7, Vector3::Arg p8,
|
||||
Vector3::Arg p9, Vector3::Arg pA, Vector3::Arg pB,
|
||||
Vector3::Arg pC, Vector3::Arg pD,
|
||||
Vector3::Arg pE,
|
||||
Vector3 * pos, Vector3 * du, Vector3 * dv);
|
||||
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_MATH_BEZIER_H
|
@ -0,0 +1,76 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#include "Frustum.h"
|
||||
#include "Box.h"
|
||||
#include "Matrix.h"
|
||||
|
||||
namespace nv
|
||||
{
|
||||
Frustum::Frustum(float fovy, float aspect, float near, float far)
|
||||
{
|
||||
// Define a frustum looking along the -ve z axis.
|
||||
planes[NEAR] = Plane(Vector3(0,0,1), near);
|
||||
planes[FAR] = Plane(Vector3(0,0,-1), far);
|
||||
|
||||
const Vector3 origin(zero);
|
||||
const float tanfy = tan(fovy/2.0f);
|
||||
planes[TOP] = Plane(Vector3( 1.0f, 0.0f, tanfy * aspect), origin);
|
||||
planes[BOTTOM] = Plane(Vector3(-1.0f, 0.0f, tanfy * aspect), origin);
|
||||
|
||||
planes[RIGHT] = Plane(Vector3(0.0f, 1.0f, tanfy), origin);
|
||||
planes[LEFT] = Plane(Vector3(0.0f, -1.0f, tanfy), origin);
|
||||
|
||||
for(int p = 0; p < Frustum::PLANE_COUNT; ++p)
|
||||
planes[p] = normalize(planes[p]);
|
||||
}
|
||||
|
||||
static void getAllCorners(const Box& boxy, Vector3 c[])
|
||||
{
|
||||
c[0] = boxy.minCorner();
|
||||
c[1] = boxy.maxCorner();
|
||||
c[2] = Vector3(c[0].x(), c[1].y(), c[0].z());
|
||||
c[3] = Vector3(c[0].x(), c[1].y(), c[1].z());
|
||||
c[4] = Vector3(c[0].x(), c[0].y(), c[1].z());
|
||||
c[5] = Vector3(c[1].x(), c[1].y(), c[0].z());
|
||||
c[6] = Vector3(c[1].x(), c[0].y(), c[0].z());
|
||||
c[7] = Vector3(c[1].x(), c[0].y(), c[1].z());
|
||||
}
|
||||
|
||||
bool Frustum::intersects(const Box& boxy) const
|
||||
{
|
||||
const int N_CORNERS = 8;
|
||||
Vector3 boxCorners[N_CORNERS];
|
||||
getAllCorners(boxy, boxCorners);
|
||||
|
||||
// test all 8 corners against the 6 sides
|
||||
// if all points are behind 1 specific plane, we are out
|
||||
// if we are in with all points, then we are fully in
|
||||
for(int p = 0; p < Frustum::PLANE_COUNT; ++p)
|
||||
{
|
||||
int iInCount = N_CORNERS;
|
||||
|
||||
for(int i = 0; i < N_CORNERS; ++i)
|
||||
{
|
||||
// test point [i] against the planes
|
||||
if (distance(planes[p], boxCorners[i]) > 0.0f)
|
||||
--iInCount;
|
||||
}
|
||||
|
||||
// were all the points outside of plane p?
|
||||
if (iInCount == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Frustum transformFrustum(const Matrix& m, const Frustum& f)
|
||||
{
|
||||
Frustum result;
|
||||
|
||||
for (int i=0; i!=Frustum::PLANE_COUNT; ++i)
|
||||
result.planes[i] = transformPlane(m, f.planes[i]);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
// This code is in the public domain -- castanyo@yahoo.es
|
||||
|
||||
#ifndef NV_MATH_FRUSTUM_H
|
||||
#define NV_MATH_FRUSTUM_H
|
||||
|
||||
#include <nvmath/Plane.h>
|
||||
|
||||
namespace nv
|
||||
{
|
||||
class Box;
|
||||
|
||||
class NVMATH_CLASS Frustum
|
||||
{
|
||||
public:
|
||||
// Construct a frustum from typical view parameters. fovy has the same meaning as for glut_perspective_reshaper.
|
||||
// The resulting frustum is centred at the origin, pointing along the z-axis.
|
||||
Frustum() {}
|
||||
Frustum(float fovy, float aspect, float near, float far);
|
||||
|
||||
// Unlike some intersection methods, we don't bother to distinguish intersects
|
||||
// from contains. A true result could indicate either.
|
||||
bool intersects(const Box&) const;
|
||||
|
||||
private:
|
||||
friend Frustum transformFrustum(const Matrix&, const Frustum&);
|
||||
|
||||
enum PlaneIndices { NEAR, LEFT, RIGHT, TOP, BOTTOM, FAR, PLANE_COUNT };
|
||||
Plane planes[PLANE_COUNT];
|
||||
};
|
||||
|
||||
Frustum transformFrustum(const Matrix&, const Frustum&);
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue