Hardcoded number of planes in frustum intersection code to 6.

This commit is contained in:
leo 2012-07-03 22:56:05 +00:00
parent d6b26e1a63
commit 1d72f82c9b
10 changed files with 102 additions and 54 deletions

View file

@ -39,7 +39,7 @@ public:
public: public:
void MinIntersectDist (LC_CLICKLINE* pLine); void MinIntersectDist (LC_CLICKLINE* pLine);
bool IntersectsVolume(const Vector4* Planes, int NumPlanes) bool IntersectsVolume(const lcVector4 Planes[6])
{ return false; } { return false; }
void Select (bool bSelecting, bool bFocus, bool bMultiple); void Select (bool bSelecting, bool bFocus, bool bMultiple);
void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z) void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z)
@ -124,7 +124,7 @@ public:
void FileSave(lcFile& file) const; void FileSave(lcFile& file) const;
void MinIntersectDist (LC_CLICKLINE* pLine); void MinIntersectDist (LC_CLICKLINE* pLine);
void Select (bool bSelecting, bool bFocus, bool bMultiple); void Select (bool bSelecting, bool bFocus, bool bMultiple);
bool IntersectsVolume(const Vector4* Planes, int NumPlanes) bool IntersectsVolume(const lcVector4 Planes[6])
{ return false; } { return false; }

View file

@ -37,7 +37,7 @@ class CurvePoint : public Object
bool FileLoad(lcFile& file); bool FileLoad(lcFile& file);
void FileSave(lcFile& file) const; void FileSave(lcFile& file) const;
void MinIntersectDist (LC_CLICKLINE* pLine); void MinIntersectDist (LC_CLICKLINE* pLine);
bool IntersectsVolume(const Vector4* Planes, int NumPlanes) bool IntersectsVolume(const lcVector4 Planes[6])
{ return false; } { return false; }
void UpdatePosition (unsigned short nTime, bool bAnimation); void UpdatePosition (unsigned short nTime, bool bAnimation);
void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz); void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz);

View file

@ -294,6 +294,16 @@ inline float lcDot(const lcVector3& a, const lcVector3& b)
return a.x * b.x + a.y * b.y + a.z * b.z; return a.x * b.x + a.y * b.y + a.z * b.z;
} }
inline float lcDot3(const lcVector4& a, const lcVector3& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
inline float lcDot3(const lcVector3& a, const lcVector4& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
inline float lcDot(const lcVector4& a, const lcVector4& b) inline float lcDot(const lcVector4& a, const lcVector4& b)
{ {
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;

View file

@ -216,9 +216,57 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
return MinIntersectDist<GLuint>(Start, End, MinDist, Intersection); return MinIntersectDist<GLuint>(Start, End, MinDist, Intersection);
} }
// Return true if a polygon intersects a set of planes. // Sutherland-Hodgman method of clipping a polygon to a plane.
static bool PolygonIntersectsPlanes(float* p1, float* p2, float* p3, float* p4, const Vector4* Planes, int NumPlanes) // TODO: move to lc_math static void lcPolygonPlaneClip(lcVector3* InPoints, int NumInPoints, lcVector3* OutPoints, int* NumOutPoints, const lcVector4& Plane)
{ {
lcVector3 *s, *p, i;
*NumOutPoints = 0;
s = &InPoints[NumInPoints-1];
for (int j = 0; j < NumInPoints; j++)
{
p = &InPoints[j];
if (lcDot3(*p, Plane) + Plane[3] <= 0)
{
if (lcDot3(*s, Plane) + Plane[3] <= 0)
{
// Both points inside.
OutPoints[*NumOutPoints] = *p;
*NumOutPoints = *NumOutPoints + 1;
}
else
{
// Outside, inside.
lcLinePlaneIntersection(i, *s, *p, Plane);
OutPoints[*NumOutPoints] = i;
*NumOutPoints = *NumOutPoints + 1;
OutPoints[*NumOutPoints] = *p;
*NumOutPoints = *NumOutPoints + 1;
}
}
else
{
if (lcDot3(*s, Plane) + Plane[3] <= 0)
{
// Inside, outside.
lcLinePlaneIntersection(i, *s, *p, Plane);
OutPoints[*NumOutPoints] = i;
*NumOutPoints = *NumOutPoints + 1;
}
}
s = p;
}
}
// Return true if a polygon intersects a set of planes.
static bool PolygonIntersectsPlanes(float* p1, float* p2, float* p3, float* p4, const lcVector4 Planes[6]) // TODO: move to lc_math
{
const int NumPlanes = 6;
float* Points[4] = { p1, p2, p3, p4 }; float* Points[4] = { p1, p2, p3, p4 };
int Outcodes[4] = { 0, 0, 0, 0 }, i; int Outcodes[4] = { 0, 0, 0, 0 }, i;
int NumPoints = (p4 != NULL) ? 4 : 3; int NumPoints = (p4 != NULL) ? 4 : 3;
@ -226,11 +274,11 @@ static bool PolygonIntersectsPlanes(float* p1, float* p2, float* p3, float* p4,
// First do the Cohen-Sutherland out code test for trivial rejects/accepts. // First do the Cohen-Sutherland out code test for trivial rejects/accepts.
for (i = 0; i < NumPoints; i++) for (i = 0; i < NumPoints; i++)
{ {
Vector3 Pt(Points[i][0], Points[i][1], Points[i][2]); lcVector3 Pt(Points[i][0], Points[i][1], Points[i][2]);
for (int j = 0; j < NumPlanes; j++) for (int j = 0; j < NumPlanes; j++)
{ {
if (Dot3(Pt, Planes[j]) + Planes[j][3] > 0) if (lcDot3(Pt, Planes[j]) + Planes[j][3] > 0)
Outcodes[i] |= 1 << j; Outcodes[i] |= 1 << j;
} }
} }
@ -257,22 +305,22 @@ static bool PolygonIntersectsPlanes(float* p1, float* p2, float* p3, float* p4,
} }
// Buffers for clipping the polygon. // Buffers for clipping the polygon.
Vector3 ClipPoints[2][8]; lcVector3 ClipPoints[2][8];
int NumClipPoints[2]; int NumClipPoints[2];
int ClipBuffer = 0; int ClipBuffer = 0;
NumClipPoints[0] = NumPoints; NumClipPoints[0] = NumPoints;
ClipPoints[0][0] = Vector3(p1[0], p1[1], p1[2]); ClipPoints[0][0] = lcVector3(p1[0], p1[1], p1[2]);
ClipPoints[0][1] = Vector3(p2[0], p2[1], p2[2]); ClipPoints[0][1] = lcVector3(p2[0], p2[1], p2[2]);
ClipPoints[0][2] = Vector3(p3[0], p3[1], p3[2]); ClipPoints[0][2] = lcVector3(p3[0], p3[1], p3[2]);
if (NumPoints == 4) if (NumPoints == 4)
ClipPoints[0][3] = Vector3(p4[0], p4[1], p4[2]); ClipPoints[0][3] = lcVector3(p4[0], p4[1], p4[2]);
// Now clip the polygon against the planes. // Now clip the polygon against the planes.
for (i = 0; i < NumPlanes; i++) for (i = 0; i < NumPlanes; i++)
{ {
PolygonPlaneClip(ClipPoints[ClipBuffer], NumClipPoints[ClipBuffer], ClipPoints[ClipBuffer^1], &NumClipPoints[ClipBuffer^1], Planes[i]); lcPolygonPlaneClip(ClipPoints[ClipBuffer], NumClipPoints[ClipBuffer], ClipPoints[ClipBuffer^1], &NumClipPoints[ClipBuffer^1], Planes[i]);
ClipBuffer ^= 1; ClipBuffer ^= 1;
if (!NumClipPoints[ClipBuffer]) if (!NumClipPoints[ClipBuffer])
@ -283,7 +331,7 @@ static bool PolygonIntersectsPlanes(float* p1, float* p2, float* p3, float* p4,
} }
template<typename IndexType> template<typename IndexType>
bool lcMesh::IntersectsPlanes(const Vector4* Planes, int NumPlanes) bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{ {
float* Verts = (float*)mVertexBuffer.mData; float* Verts = (float*)mVertexBuffer.mData;
@ -297,19 +345,19 @@ bool lcMesh::IntersectsPlanes(const Vector4* Planes, int NumPlanes)
IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType); IndexType* Indices = (IndexType*)mIndexBuffer.mData + Section->IndexOffset / sizeof(IndexType);
for (int Idx = 0; Idx < Section->NumIndices; Idx += 3) for (int Idx = 0; Idx < Section->NumIndices; Idx += 3)
if (PolygonIntersectsPlanes(&Verts[Indices[Idx]*3], &Verts[Indices[Idx+1]*3], &Verts[Indices[Idx+2]*3], NULL, Planes, NumPlanes)) if (PolygonIntersectsPlanes(&Verts[Indices[Idx]*3], &Verts[Indices[Idx+1]*3], &Verts[Indices[Idx+2]*3], NULL, Planes))
return true; return true;
} }
return false; return false;
} }
bool lcMesh::IntersectsPlanes(const Vector4* Planes, int NumPlanes) bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{ {
if (mIndexType == GL_UNSIGNED_SHORT) if (mIndexType == GL_UNSIGNED_SHORT)
return IntersectsPlanes<GLushort>(Planes, NumPlanes); return IntersectsPlanes<GLushort>(Planes);
else else
return IntersectsPlanes<GLuint>(Planes, NumPlanes); return IntersectsPlanes<GLuint>(Planes);
} }
template<typename IndexType> template<typename IndexType>

View file

@ -3,7 +3,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "opengl.h" #include "opengl.h"
#include "algebra.h"
class lcVertexBuffer class lcVertexBuffer
{ {
@ -129,8 +128,8 @@ public:
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection); bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection);
template<typename IndexType> template<typename IndexType>
bool IntersectsPlanes(const Vector4* Planes, int NumPlanes); bool IntersectsPlanes(const lcVector4 Planes[6]);
bool IntersectsPlanes(const Vector4* Planes, int NumPlanes); bool IntersectsPlanes(const lcVector4 Planes[6]);
void UpdateBuffers() void UpdateBuffers()
{ {

View file

@ -32,7 +32,7 @@ public:
public: public:
void MinIntersectDist (LC_CLICKLINE* pLine); void MinIntersectDist (LC_CLICKLINE* pLine);
bool IntersectsVolume(const Vector4* Planes, int NumPlanes) bool IntersectsVolume(const lcVector4 Planes[6])
{ return false; } { return false; }
void Select (bool bSelecting, bool bFocus, bool bMultiple); void Select (bool bSelecting, bool bFocus, bool bMultiple);
void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z) void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float x, float y, float z)
@ -98,7 +98,7 @@ public:
void Render (float fLineWidth); void Render (float fLineWidth);
void MinIntersectDist (LC_CLICKLINE* Line); void MinIntersectDist (LC_CLICKLINE* Line);
bool IntersectsVolume(const Vector4* Planes, int NumPlanes) bool IntersectsVolume(const lcVector4 Planes[6])
{ return false; } { return false; }
void UpdatePosition (unsigned short nTime, bool bAnimation); void UpdatePosition (unsigned short nTime, bool bAnimation);
void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz); void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz);

View file

@ -81,7 +81,7 @@ public:
virtual void Select(bool bSelecting, bool bFocus, bool bMultiple) = 0; virtual void Select(bool bSelecting, bool bFocus, bool bMultiple) = 0;
// Check if the object intersects the volume specified by a given set of planes. // Check if the object intersects the volume specified by a given set of planes.
virtual bool IntersectsVolume(const class Vector4* Planes, int NumPlanes) = 0; virtual bool IntersectsVolume(const lcVector4 Planes[6]) = 0;
/* /*

View file

@ -15,7 +15,6 @@
#include "piece.h" #include "piece.h"
#include "group.h" #include "group.h"
#include "project.h" #include "project.h"
#include "algebra.h"
#include "lc_application.h" #include "lc_application.h"
#define LC_PIECE_SAVE_VERSION 11 // LeoCAD 0.77 #define LC_PIECE_SAVE_VERSION 11 // LeoCAD 0.77
@ -412,33 +411,33 @@ void Piece::MinIntersectDist(LC_CLICKLINE* pLine)
pLine->pClosest = this; pLine->pClosest = this;
} }
bool Piece::IntersectsVolume(const Vector4* Planes, int NumPlanes) bool Piece::IntersectsVolume(const lcVector4 Planes[6])
{ {
// First check the bounding box for quick rejection. // First check the bounding box for quick rejection.
Vector3 Box[8] = lcVector3 Box[8] =
{ {
Vector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[5]), lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[5]),
Vector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[5]), lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[5]),
Vector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2]), lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2]),
Vector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]), lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]),
Vector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[2]), lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[2]),
Vector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[2]), lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[2]),
Vector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]), lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]),
Vector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2]) lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2])
}; };
// Transform the planes to local space. // Transform the planes to local space.
Matrix44 WorldToLocal; lcMatrix44 WorldToLocal = lcMatrix44FromAxisAngle(lcVector3(mRotation[0], mRotation[1], mRotation[2]), -mRotation[3] * LC_DTOR);
WorldToLocal.CreateFromAxisAngle(Vector3(mRotation[0], mRotation[1], mRotation[2]), -mRotation[3] * LC_DTOR); WorldToLocal.SetTranslation(lcMul31(lcVector3(-mPosition[0], -mPosition[1], -mPosition[2]), WorldToLocal));
WorldToLocal.SetTranslation(Mul31(Vector3(-mPosition[0], -mPosition[1], -mPosition[2]), WorldToLocal));
Vector4* LocalPlanes = new Vector4[NumPlanes]; const int NumPlanes = 6;
lcVector4 LocalPlanes[NumPlanes];
int i; int i;
for (i = 0; i < NumPlanes; i++) for (i = 0; i < NumPlanes; i++)
{ {
LocalPlanes[i] = Mul30(Vector3(Planes[i]), WorldToLocal); lcVector3 PlaneNormal = lcMul30(lcVector3(Planes[i][0], Planes[i][1], Planes[i][2]), WorldToLocal);
LocalPlanes[i][3] = Planes[i][3] - Dot3(Vector3(WorldToLocal[3]), Vector3(LocalPlanes[i])); LocalPlanes[i] = lcVector4(PlaneNormal, Planes[i][3] - lcDot3(WorldToLocal[3], PlaneNormal));
} }
// Start by testing trivial reject/accept cases. // Start by testing trivial reject/accept cases.
@ -450,7 +449,7 @@ bool Piece::IntersectsVolume(const Vector4* Planes, int NumPlanes)
for (int j = 0; j < NumPlanes; j++) for (int j = 0; j < NumPlanes; j++)
{ {
if (Dot3(Box[i], LocalPlanes[j]) + LocalPlanes[j][3] > 0) if (lcDot3(Box[i], LocalPlanes[j]) + LocalPlanes[j][3] > 0)
Outcodes[i] |= 1 << j; Outcodes[i] |= 1 << j;
} }
} }
@ -465,22 +464,14 @@ bool Piece::IntersectsVolume(const Vector4* Planes, int NumPlanes)
// All corners outside the same plane. // All corners outside the same plane.
if (OutcodesAND != 0) if (OutcodesAND != 0)
{
delete[] LocalPlanes;
return false; return false;
}
// All corners inside the volume. // All corners inside the volume.
if (OutcodesOR == 0) if (OutcodesOR == 0)
{
delete[] LocalPlanes;
return true; return true;
}
// Partial intersection, so check if any triangles are inside. // Partial intersection, so check if any triangles are inside.
bool Hit = mPieceInfo->mMesh->IntersectsPlanes(LocalPlanes, NumPlanes); bool Hit = mPieceInfo->mMesh->IntersectsPlanes(LocalPlanes);
delete[] LocalPlanes;
return Hit; return Hit;
} }

View file

@ -29,7 +29,7 @@ public:
void Select (bool bSelecting, bool bFocus, bool bMultiple); void Select (bool bSelecting, bool bFocus, bool bMultiple);
virtual void InsertTime (unsigned short start, bool animation, unsigned short time); virtual void InsertTime (unsigned short start, bool animation, unsigned short time);
virtual void RemoveTime (unsigned short start, bool animation, unsigned short time); virtual void RemoveTime (unsigned short start, bool animation, unsigned short time);
virtual bool IntersectsVolume(const Vector4* Planes, int NumPlanes); virtual bool IntersectsVolume(const lcVector4 Planes[6]);

View file

@ -6297,7 +6297,7 @@ void Project::FindObjectsInBox(float x1, float y1, float x2, float y2, PtrArray<
{ {
if (piece->IsVisible(m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation)) if (piece->IsVisible(m_bAnimation ? m_nCurFrame : m_nCurStep, m_bAnimation))
{ {
if (piece->IntersectsVolume((Vector4*)Planes, 6)) if (piece->IntersectsVolume(Planes))
Objects.Add(piece); Objects.Add(piece);
} }
} }