262 lines
7.8 KiB
C++
262 lines
7.8 KiB
C++
#include "SCENE.h"
|
|
//#pragma optimize("",off)
|
|
float PIKING_EPSILLON = 0.0f;
|
|
void DrawInterface::PickMesh(Mesh *pMyMesh,u32 Num, u32 Base)
|
|
{
|
|
if (MotherClass && MotherClass->PickReportCurrent.PickFrozed) return;
|
|
|
|
if (
|
|
(ScissorRect.right > MousePicking.x) ||
|
|
(ScissorRect.top > FB_SY - MousePicking.y) ||
|
|
(ScissorRect.bottom < FB_SY - MousePicking.y) ||
|
|
(ScissorRect.left < MousePicking.x)
|
|
)
|
|
return;
|
|
|
|
START_RASTER(Picking);
|
|
SAVE_MATRIXES();
|
|
|
|
|
|
|
|
|
|
|
|
u32 AlphaThreshold;
|
|
AlphaThreshold = 0;
|
|
if (CurrentRS.PICKABLE_NO_TRANSPARENCY == 0)
|
|
if ((CurrentRS.BlendingMode == 1)||(CurrentRS.BlendingMode == 3)) AlphaThreshold = MotherClass->PickReportCurrent.AlphaThreshold;
|
|
|
|
float Viewport[4];
|
|
//glGetFloatv(GL_VIEWPORT,Viewport);
|
|
memcpy(Viewport, CurrentViewport, sizeof(Viewport));
|
|
|
|
u32 Counter;
|
|
FaceIndex *Indexes;
|
|
FaceIndex *Indexes_UV;
|
|
Vector Fake;
|
|
Vector MouseVector;
|
|
Vector *PointsUV,*Points;
|
|
|
|
Points = pMyMesh->Points;
|
|
PointsUV = pMyMesh->PointsUV;
|
|
if (!Points) Points = &Fake;
|
|
if (!PointsUV) PointsUV = &Fake;
|
|
|
|
Indexes = pMyMesh->Indexes + Base;
|
|
Indexes_UV = pMyMesh->Indexes_UV + Base;
|
|
|
|
float TransMat[16];
|
|
|
|
Vector I,J,K,L;
|
|
|
|
Mul4x4Matrix(_4x4_Model,_4x4_Persp,TransMat);
|
|
I.x = TransMat[0];
|
|
I.y = TransMat[4];
|
|
I.z = TransMat[8];
|
|
J.x = TransMat[0+1];
|
|
J.y = TransMat[4+1];
|
|
J.z = TransMat[8+1];
|
|
K.x = TransMat[0+2];
|
|
K.y = TransMat[4+2];
|
|
K.z = TransMat[8+2];
|
|
L.x = TransMat[0+3];
|
|
L.y = TransMat[4+3];
|
|
L.z = TransMat[8+3];
|
|
|
|
|
|
if (Num == -1)
|
|
Counter = pMyMesh->NumberOfFaces;
|
|
else
|
|
Counter = Num;
|
|
|
|
|
|
MouseVector.x = (MousePicking.x) - FB_SX/2.0f;
|
|
MouseVector.y = (FB_SY - MousePicking.y ) - FB_SY/2.0f;
|
|
|
|
MouseVector.x += (float)FB_SX/2.0f - Viewport[0] - Viewport[2] / 2.0f;
|
|
MouseVector.y += (float)FB_SY/2.0f - Viewport[1] - Viewport[3] / 2.0f;
|
|
|
|
MouseVector.x *= 2.0f / Viewport[2] ;
|
|
MouseVector.y *= 2.0f / Viewport[3] ;
|
|
|
|
if ((fabs(MouseVector.x) < 1.0f) && (fabs(MouseVector.y) < 1.0f) )
|
|
{
|
|
while (Counter--)
|
|
{
|
|
Vector *P1,*P2,*P3;
|
|
Vector Pr1,Pr2,Pr3;
|
|
Vector Po1,Po2,Po3;
|
|
float Pw1,Pw2,Pw3;
|
|
float aPw1,aPw2,aPw3;
|
|
float D1,D2,D3;
|
|
P1 = Points + Indexes->I[0];
|
|
P2 = Points + Indexes->I[1];
|
|
P3 = Points + Indexes->I[2];
|
|
Pw1 = ( *P1 * L ) + TransMat[15];
|
|
Pw2 = ( *P2 * L ) + TransMat[15];
|
|
Pw3 = ( *P3 * L ) + TransMat[15];
|
|
if ((Pw1 > 0.0f) || (Pw2 > 0.0f) || (Pw3 > 0.0f))
|
|
{
|
|
Pr1.x = ( *P1 * I ) + TransMat[12];
|
|
Pr1.y = ( *P1 * J ) + TransMat[13];
|
|
Pr1.z = ( *P1 * K ) + TransMat[14];
|
|
Pr2.x = ( *P2 * I ) + TransMat[12];
|
|
Pr2.y = ( *P2 * J ) + TransMat[13];
|
|
Pr2.z = ( *P2 * K ) + TransMat[14];
|
|
Pr3.x = ( *P3 * I ) + TransMat[12];
|
|
Pr3.y = ( *P3 * J ) + TransMat[13];
|
|
Pr3.z = ( *P3 * K ) + TransMat[14];
|
|
Po1 = Pr1;
|
|
Po2 = Pr2;
|
|
Po3 = Pr3;
|
|
if (Pw1 < 0) aPw1 = 1.0f/1000000.0f;
|
|
if (Pw2 < 0) aPw2 = 1.0f/1000000.0f;
|
|
if (Pw3 < 0) aPw3 = 1.0f/1000000.0f;
|
|
|
|
aPw1 = fabs(Pw1);
|
|
aPw2 = fabs(Pw2);
|
|
aPw3 = fabs(Pw3);
|
|
Pr1 *= 1.0f / aPw1;
|
|
Pr2 *= 1.0f / aPw2;
|
|
Pr3 *= 1.0f / aPw3;
|
|
|
|
D1 = MouseVector.DistanceToLineXY(Pr3 , Pr2);
|
|
D2 = MouseVector.DistanceToLineXY(Pr1 , Pr3);
|
|
D3 = MouseVector.DistanceToLineXY(Pr2 , Pr1);
|
|
u32 Pos;
|
|
Pos = 0;
|
|
#define EPSILON 0.0
|
|
if ((D1 >= -EPSILON) && (D2 >= -EPSILON) && (D3 >= -EPSILON)) Pos |= 1;
|
|
if ((D1 <= EPSILON) && (D2 <= EPSILON) && (D3 <= EPSILON)) Pos |= 2; // OGL FRONTFACE
|
|
if (CurrentRS.BACKFACE)
|
|
{
|
|
if ((Pos == 1) && (CurrentRS.BACKFACE_INVERT)) Pos = 0;
|
|
if ((Pos == 2) && (!CurrentRS.BACKFACE_INVERT)) Pos = 0;
|
|
}
|
|
if (Pos)
|
|
{
|
|
Vector IP,IP3D;
|
|
float IPw;
|
|
u32 Color;
|
|
Color = 0xff;
|
|
if ((Pw1 < 0.0f) || (Pw2 < 0.0f) || (Pw3 < 0.0f)) Color = 0xff00;
|
|
D1 /= Pr1.DistanceToLineXY(Pr2 , Pr3);
|
|
D2 /= Pr2.DistanceToLineXY(Pr3 , Pr1);
|
|
D3 /= Pr3.DistanceToLineXY(Pr1 , Pr2);
|
|
D1 = fabs(D1);
|
|
D2 = fabs(D2);
|
|
D3 = fabs(D3);
|
|
IP = Po1 * D1 + Po2 * D2 + Po3 * D3;
|
|
IPw = Pw1 * D1 + Pw2 * D2 + Pw3 * D3;
|
|
IP *= 1.0f / IPw;
|
|
u32 TestResult = (MousePickingCurrentZ <= IP.z + PIKING_EPSILLON);
|
|
if (CurrentRS.ZEQUAL && (MousePickingCurrentZ != IP.z)) TestResult = 0;
|
|
if (CurrentRS.ZPASS || CurrentRS.NOZTEST || (TestResult))
|
|
{
|
|
|
|
u32 OKAffect = 1;
|
|
Vector IPUVW;
|
|
|
|
|
|
IPw = D1/aPw1 + D2/aPw2 + D3/aPw3;
|
|
IP3D = *(Points + Indexes->I[0]) * (D1/aPw1) +
|
|
*(Points + Indexes->I[1]) * (D2/aPw2) +
|
|
*(Points + Indexes->I[2]) * (D3/aPw3);
|
|
IP3D *= 1.0f / IPw;
|
|
|
|
Vector UVW;
|
|
UVW = *(PointsUV + Indexes_UV->I[0]) * (D1/aPw1) +
|
|
*(PointsUV + Indexes_UV->I[1]) * (D2/aPw2) +
|
|
*(PointsUV + Indexes_UV->I[2]) * (D3/aPw3) ;
|
|
UVW *= 1.0f / IPw;
|
|
|
|
IPUVW.x = UVW.x * _4x4_Texture[0] + UVW.y * _4x4_Texture[4] + _4x4_Texture[12];
|
|
IPUVW.y = UVW.x * _4x4_Texture[1] + UVW.y * _4x4_Texture[5] + _4x4_Texture[13];
|
|
IPUVW.z = UVW.x * _4x4_Texture[3] + UVW.y * _4x4_Texture[7] + _4x4_Texture[15];
|
|
if (IPUVW.z && (IPUVW.z != 1.0f))
|
|
{
|
|
IPUVW.x /= IPUVW.z;
|
|
IPUVW.y /= IPUVW.z;
|
|
}
|
|
|
|
/* Affect Here */
|
|
if (ulCurrentTexture != -1)
|
|
{
|
|
u32 PX,PY;
|
|
PX = (u32)(IPUVW.x * (float)GetUpperPO2(AllRef[ulCurrentTexture].pExtRef->SX));
|
|
PY = (u32)(IPUVW.y * (float)GetUpperPO2(AllRef[ulCurrentTexture].pExtRef->SY));
|
|
PX %= AllRef[ulCurrentTexture].pExtRef->SX;
|
|
PY %= AllRef[ulCurrentTexture].pExtRef->SY;
|
|
/*IPUVW.x = IPUVW.x - floor(IPUVW.x);
|
|
IPUVW.y = IPUVW.y - floor(IPUVW.y);*/
|
|
IPUVW.x *= (float)AllRef[ulCurrentTexture].pExtRef->SX;
|
|
IPUVW.y *= (float)AllRef[ulCurrentTexture].pExtRef->SY;
|
|
/*IPUVW.x = PX;
|
|
IPUVW.y = PY;*/
|
|
|
|
if (AlphaThreshold)
|
|
{
|
|
if (AlphaThreshold > AllRef[ulCurrentTexture].pExtRef->GetValue(PX + PY * AllRef[ulCurrentTexture].pExtRef->PITCH)>>24)
|
|
OKAffect = 0;
|
|
}
|
|
}
|
|
|
|
if (OKAffect)
|
|
{
|
|
if (!CurrentRS.NOZWRITE)
|
|
{
|
|
MousePickingCurrentZ = IP.z;
|
|
}
|
|
MousePickingXYZ = IP3D;
|
|
MousePickingUVW = IPUVW;
|
|
MousePickingTri = Counter;
|
|
|
|
if (MotherClass)
|
|
{
|
|
memcpy(&MotherClass->PickReportResult,&MotherClass->PickReportCurrent,sizeof(PickingReport));
|
|
MotherClass->PickReportResult.CollidedMap = NULL;
|
|
if (ulCurrentTexture != -1)
|
|
MotherClass->PickReportResult.CollidedMap = AllRef[ulCurrentTexture].pExtRef;
|
|
if (MotherClass->PickReportResult.CollidedMap == NULL)
|
|
ulCurrentTexture = ulCurrentTexture;
|
|
|
|
|
|
MotherClass->PickReportResult.PickingCoordUV = MousePickingUVW;
|
|
MotherClass->PickReportResult.PickingCoordXYZ_Global = MotherClass->PickReportResult.CurrentGlobalMatrix * IP3D;
|
|
MotherClass->PickReportResult.PickingCoordXYZ_Local = IP3D;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Indexes++;
|
|
Indexes_UV++;
|
|
}
|
|
}
|
|
//RESTORE_MATRIXES();
|
|
STOP_RASTER(Picking);
|
|
}
|
|
|
|
void DrawInterface::PickQuad(u32 Color,float X, float Y,float Xsize, float Ysize,float TX,float TY,float TW,float TH)
|
|
{
|
|
if (MotherClass && MotherClass->PickReportCurrent.PickFrozed) return;
|
|
X-=MotherClass->PickReportCurrent.GrowCaptureSize;
|
|
Y-=MotherClass->PickReportCurrent.GrowCaptureSize;
|
|
Xsize += MotherClass->PickReportCurrent.GrowCaptureSize * 2.0f;
|
|
Ysize += MotherClass->PickReportCurrent.GrowCaptureSize * 2.0f;
|
|
Vector QuadXYZ[4] = {Vector(X,Y,ZQuad),Vector(X+Xsize,Y,ZQuad),Vector(X+Xsize,Y+Ysize,ZQuad),Vector(X,Y+Ysize,ZQuad)};;
|
|
Vector QuadUV[4] = {Vector(TX,TY,0),Vector(TX+TW,TY,0),Vector(TX+TW,TY+TH,0),Vector(TX,TY+TH,0)};
|
|
FaceIndex FIndexes[2] = {{0,1,2},{0,2,3}};
|
|
Mesh MyPMesh;
|
|
MyPMesh.NumberOfPoints = 4;
|
|
MyPMesh.NumberOfPointsUV = 4;
|
|
MyPMesh.Points = (Vector *)QuadXYZ;
|
|
MyPMesh.PointsUV = (Vector *)QuadUV;
|
|
MyPMesh.NumberOfFaces = 2;
|
|
MyPMesh.Indexes = (FaceIndex*)FIndexes;
|
|
MyPMesh.Indexes_UV = (FaceIndex*)FIndexes;
|
|
PickMesh(&MyPMesh,-1, 0);
|
|
}
|