JD2022-TU1/main/extern/Camcam/LIBS/Render/RENDER_Picking.cpp

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);
}