mirror of
https://github.com/leozide/leocad
synced 2025-01-17 18:11:42 +01:00
Hardcoded number of planes in frustum intersection code to 6.
This commit is contained in:
parent
d6b26e1a63
commit
1d72f82c9b
10 changed files with 102 additions and 54 deletions
|
@ -39,7 +39,7 @@ public:
|
|||
|
||||
public:
|
||||
void MinIntersectDist (LC_CLICKLINE* pLine);
|
||||
bool IntersectsVolume(const Vector4* Planes, int NumPlanes)
|
||||
bool IntersectsVolume(const lcVector4 Planes[6])
|
||||
{ return false; }
|
||||
void Select (bool bSelecting, bool bFocus, bool bMultiple);
|
||||
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 MinIntersectDist (LC_CLICKLINE* pLine);
|
||||
void Select (bool bSelecting, bool bFocus, bool bMultiple);
|
||||
bool IntersectsVolume(const Vector4* Planes, int NumPlanes)
|
||||
bool IntersectsVolume(const lcVector4 Planes[6])
|
||||
{ return false; }
|
||||
|
||||
|
||||
|
|
|
@ -37,8 +37,8 @@ class CurvePoint : public Object
|
|||
bool FileLoad(lcFile& file);
|
||||
void FileSave(lcFile& file) const;
|
||||
void MinIntersectDist (LC_CLICKLINE* pLine);
|
||||
bool IntersectsVolume(const Vector4* Planes, int NumPlanes)
|
||||
{ return false; }
|
||||
bool IntersectsVolume(const lcVector4 Planes[6])
|
||||
{ return false; }
|
||||
void UpdatePosition (unsigned short nTime, bool bAnimation);
|
||||
void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz);
|
||||
void Render (LC_RENDER_INFO* pInfo);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
|
||||
|
|
|
@ -216,9 +216,57 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
|
|||
return MinIntersectDist<GLuint>(Start, End, MinDist, Intersection);
|
||||
}
|
||||
|
||||
// Return true if a polygon intersects a set of planes.
|
||||
static bool PolygonIntersectsPlanes(float* p1, float* p2, float* p3, float* p4, const Vector4* Planes, int NumPlanes) // TODO: move to lc_math
|
||||
// Sutherland-Hodgman method of clipping a polygon to a plane.
|
||||
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 };
|
||||
int Outcodes[4] = { 0, 0, 0, 0 }, i;
|
||||
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.
|
||||
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++)
|
||||
{
|
||||
if (Dot3(Pt, Planes[j]) + Planes[j][3] > 0)
|
||||
if (lcDot3(Pt, Planes[j]) + Planes[j][3] > 0)
|
||||
Outcodes[i] |= 1 << j;
|
||||
}
|
||||
}
|
||||
|
@ -257,22 +305,22 @@ static bool PolygonIntersectsPlanes(float* p1, float* p2, float* p3, float* p4,
|
|||
}
|
||||
|
||||
// Buffers for clipping the polygon.
|
||||
Vector3 ClipPoints[2][8];
|
||||
lcVector3 ClipPoints[2][8];
|
||||
int NumClipPoints[2];
|
||||
int ClipBuffer = 0;
|
||||
|
||||
NumClipPoints[0] = NumPoints;
|
||||
ClipPoints[0][0] = Vector3(p1[0], p1[1], p1[2]);
|
||||
ClipPoints[0][1] = Vector3(p2[0], p2[1], p2[2]);
|
||||
ClipPoints[0][2] = Vector3(p3[0], p3[1], p3[2]);
|
||||
ClipPoints[0][0] = lcVector3(p1[0], p1[1], p1[2]);
|
||||
ClipPoints[0][1] = lcVector3(p2[0], p2[1], p2[2]);
|
||||
ClipPoints[0][2] = lcVector3(p3[0], p3[1], p3[2]);
|
||||
|
||||
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.
|
||||
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;
|
||||
|
||||
if (!NumClipPoints[ClipBuffer])
|
||||
|
@ -283,7 +331,7 @@ static bool PolygonIntersectsPlanes(float* p1, float* p2, float* p3, float* p4,
|
|||
}
|
||||
|
||||
template<typename IndexType>
|
||||
bool lcMesh::IntersectsPlanes(const Vector4* Planes, int NumPlanes)
|
||||
bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
|
||||
{
|
||||
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);
|
||||
|
||||
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 false;
|
||||
}
|
||||
|
||||
bool lcMesh::IntersectsPlanes(const Vector4* Planes, int NumPlanes)
|
||||
bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
|
||||
{
|
||||
if (mIndexType == GL_UNSIGNED_SHORT)
|
||||
return IntersectsPlanes<GLushort>(Planes, NumPlanes);
|
||||
return IntersectsPlanes<GLushort>(Planes);
|
||||
else
|
||||
return IntersectsPlanes<GLuint>(Planes, NumPlanes);
|
||||
return IntersectsPlanes<GLuint>(Planes);
|
||||
}
|
||||
|
||||
template<typename IndexType>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include "opengl.h"
|
||||
#include "algebra.h"
|
||||
|
||||
class lcVertexBuffer
|
||||
{
|
||||
|
@ -129,8 +128,8 @@ public:
|
|||
bool MinIntersectDist(const lcVector3& Start, const lcVector3& End, float& MinDist, lcVector3& Intersection);
|
||||
|
||||
template<typename IndexType>
|
||||
bool IntersectsPlanes(const Vector4* Planes, int NumPlanes);
|
||||
bool IntersectsPlanes(const Vector4* Planes, int NumPlanes);
|
||||
bool IntersectsPlanes(const lcVector4 Planes[6]);
|
||||
bool IntersectsPlanes(const lcVector4 Planes[6]);
|
||||
|
||||
void UpdateBuffers()
|
||||
{
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
|
||||
public:
|
||||
void MinIntersectDist (LC_CLICKLINE* pLine);
|
||||
bool IntersectsVolume(const Vector4* Planes, int NumPlanes)
|
||||
bool IntersectsVolume(const lcVector4 Planes[6])
|
||||
{ return false; }
|
||||
void Select (bool bSelecting, bool bFocus, bool bMultiple);
|
||||
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 MinIntersectDist (LC_CLICKLINE* Line);
|
||||
bool IntersectsVolume(const Vector4* Planes, int NumPlanes)
|
||||
bool IntersectsVolume(const lcVector4 Planes[6])
|
||||
{ return false; }
|
||||
void UpdatePosition (unsigned short nTime, bool bAnimation);
|
||||
void Move (unsigned short nTime, bool bAnimation, bool bAddKey, float dx, float dy, float dz);
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
virtual void Select(bool bSelecting, bool bFocus, bool bMultiple) = 0;
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "piece.h"
|
||||
#include "group.h"
|
||||
#include "project.h"
|
||||
#include "algebra.h"
|
||||
#include "lc_application.h"
|
||||
|
||||
#define LC_PIECE_SAVE_VERSION 11 // LeoCAD 0.77
|
||||
|
@ -412,33 +411,33 @@ void Piece::MinIntersectDist(LC_CLICKLINE* pLine)
|
|||
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.
|
||||
Vector3 Box[8] =
|
||||
lcVector3 Box[8] =
|
||||
{
|
||||
Vector3(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]),
|
||||
Vector3(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]),
|
||||
Vector3(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]),
|
||||
Vector3(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[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[5]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[5]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[2]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[2]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[0], mPieceInfo->m_fDimensions[4], mPieceInfo->m_fDimensions[5]),
|
||||
lcVector3(mPieceInfo->m_fDimensions[3], mPieceInfo->m_fDimensions[1], mPieceInfo->m_fDimensions[2])
|
||||
};
|
||||
|
||||
// Transform the planes to local space.
|
||||
Matrix44 WorldToLocal;
|
||||
WorldToLocal.CreateFromAxisAngle(Vector3(mRotation[0], mRotation[1], mRotation[2]), -mRotation[3] * LC_DTOR);
|
||||
WorldToLocal.SetTranslation(Mul31(Vector3(-mPosition[0], -mPosition[1], -mPosition[2]), WorldToLocal));
|
||||
lcMatrix44 WorldToLocal = lcMatrix44FromAxisAngle(lcVector3(mRotation[0], mRotation[1], mRotation[2]), -mRotation[3] * LC_DTOR);
|
||||
WorldToLocal.SetTranslation(lcMul31(lcVector3(-mPosition[0], -mPosition[1], -mPosition[2]), WorldToLocal));
|
||||
|
||||
Vector4* LocalPlanes = new Vector4[NumPlanes];
|
||||
const int NumPlanes = 6;
|
||||
lcVector4 LocalPlanes[NumPlanes];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NumPlanes; i++)
|
||||
{
|
||||
LocalPlanes[i] = Mul30(Vector3(Planes[i]), WorldToLocal);
|
||||
LocalPlanes[i][3] = Planes[i][3] - Dot3(Vector3(WorldToLocal[3]), Vector3(LocalPlanes[i]));
|
||||
lcVector3 PlaneNormal = lcMul30(lcVector3(Planes[i][0], Planes[i][1], Planes[i][2]), WorldToLocal);
|
||||
LocalPlanes[i] = lcVector4(PlaneNormal, Planes[i][3] - lcDot3(WorldToLocal[3], PlaneNormal));
|
||||
}
|
||||
|
||||
// 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++)
|
||||
{
|
||||
if (Dot3(Box[i], LocalPlanes[j]) + LocalPlanes[j][3] > 0)
|
||||
if (lcDot3(Box[i], LocalPlanes[j]) + LocalPlanes[j][3] > 0)
|
||||
Outcodes[i] |= 1 << j;
|
||||
}
|
||||
}
|
||||
|
@ -465,22 +464,14 @@ bool Piece::IntersectsVolume(const Vector4* Planes, int NumPlanes)
|
|||
|
||||
// All corners outside the same plane.
|
||||
if (OutcodesAND != 0)
|
||||
{
|
||||
delete[] LocalPlanes;
|
||||
return false;
|
||||
}
|
||||
|
||||
// All corners inside the volume.
|
||||
if (OutcodesOR == 0)
|
||||
{
|
||||
delete[] LocalPlanes;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Partial intersection, so check if any triangles are inside.
|
||||
bool Hit = mPieceInfo->mMesh->IntersectsPlanes(LocalPlanes, NumPlanes);
|
||||
|
||||
delete[] LocalPlanes;
|
||||
bool Hit = mPieceInfo->mMesh->IntersectsPlanes(LocalPlanes);
|
||||
|
||||
return Hit;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
void Select (bool bSelecting, bool bFocus, bool bMultiple);
|
||||
virtual void InsertTime (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]);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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->IntersectsVolume((Vector4*)Planes, 6))
|
||||
if (piece->IntersectsVolume(Planes))
|
||||
Objects.Add(piece);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue