www.pudn.com > coolMEMORY.rar > AS_Stuff.cpp
//-----------------------------------------------------------------------------
// File: AS_Stuff.cpp
//-----------------------------------------------------------------------------
#include "AS_Engine.h"
AS_3D_VECTOR ASClosestPointOnLine(AS_3D_VECTOR vA, AS_3D_VECTOR vB, AS_3D_VECTOR vP)
{ // begin ASClosestPointOnLine()
// Determine dT: (the length of the vector from ‘dA’ to ‘dP’)
AS_3D_VECTOR vC = vP-vA;
AS_3D_VECTOR vV = vB-vA;
double dD = vV.GetLength();
vV.Normalize();
double dT = vV.DotProduct(vC);
// Check to see if ‘dT’ is beyond the extents of the line segment:
if(dT < 0.0f)
return vA;
if(dT > dD)
return vB;
// Return the point between ‘vA’ and ‘vB’
// set length of vV to dT. vV is normalized so this is easy:
vV *= (float) dT;
return (vA+vV);
} // end ASClosestPointOnLine()
AS_3D_VECTOR ASClosestPointOnTriangle(AS_3D_VECTOR vA, AS_3D_VECTOR vB,
AS_3D_VECTOR vC, AS_3D_VECTOR vP)
{ // begin ASClosestPointOnTriangle()
AS_3D_VECTOR vRab = ASClosestPointOnLine(vA, vB, vP);
AS_3D_VECTOR vRbc = ASClosestPointOnLine(vB, vC, vP);
AS_3D_VECTOR vRca = ASClosestPointOnLine(vC, vA, vP);
double dAB = (vP-vRab).GetLength();
double dBC = (vP-vRbc).GetLength();
double dCA = (vP-vRca).GetLength();
double dMin = dAB;
AS_3D_VECTOR vResult = vRab;
if(dBC < dMin)
{
dMin = dBC;
vResult = vRbc;
}
if(dCA < dMin)
vResult = vRca;
return vResult;
} // end ASClosestPointOnTriangle()
AS_DLIGHT::AS_DLIGHT(void)
{ // begin AS_DLIGHT::AS_DLIGHT()
fRadius = 3.0f;
vColor.fX = 1.0f;
vColor.fY = 1.0f;
vColor.fZ = 1.0f;
} // end AS_DLIGHT::AS_DLIGHT()
AS_DLIGHT::~AS_DLIGHT(void)
{ // begin AS_DLIGHT::~AS_DLIGHT()
} // end AS_DLIGHT::~AS_DLIGHT()
void AS_DLIGHT::Light(AS_3D_VECTOR vV1, AS_3D_VECTOR vV2, AS_3D_VECTOR vV3)
{ // begin AS_DLIGHT::Light()
// Polygons plane:
AS_PLANE Plane(vV1, vV2, vV3);
//distance to polygon
double distance = fabs(Plane.DistanceToPlane( vPos ));
// Too far: don't light the polygon:
if(distance >= fRadius)
return;
// Nearest point to plane
// (inersection from light pos in dir of plane normal)
AS_3D_VECTOR vNearest = Plane.RayIntersection( vPos, Plane.vN);
if(((vPos-vNearest).DotProduct(Plane.vN)) < 0.0)
return;
AS_3D_VECTOR vClosest = ASClosestPointOnTriangle(vV1, vV2, vV3, vNearest);
float fDis = (vClosest-vPos).GetLength();
if(fDis >= fRadius)
return;
// Calculate plane normals:
AS_3D_VECTOR vPNormal2 = ((vV1-vV2).CrossProduct(vV1-vV3)).Normalize();
AS_3D_VECTOR vUp(1.0f, 0.0f, 0.0f);
AS_3D_VECTOR vPolygonHorizontal = (vPNormal2.CrossProduct(vUp)).Normalize();
AS_3D_VECTOR vPolygonVertical = (vPolygonHorizontal.CrossProduct(vPNormal2)).Normalize();
float brightness = 1.0f - fDis/fRadius;
float fScale = 1.0f/(fRadius+fDis*2.5f);
// Intense is dependable on distance:
glColor4d(vColor.fX * brightness, vColor.fY * brightness,
vColor.fZ * brightness, 1.0);
float fTX, fTY;
// Vector from polygons vertex to nearest point:
AS_3D_VECTOR vVerNear = vV1-vNearest;
fTX = (float) (vVerNear.DotProduct(vPolygonHorizontal*fScale)+0.5f);
if(fTX > 1.0f)
fTX = 1.0f;
if(fTX < 0.0f)
fTX = 0.0f;
fTY = (float) (vVerNear.DotProduct(vPolygonVertical*fScale)+0.5f);
if(fTY > 1.0f)
fTY = 1.0f;
if(fTY < 0.0f)
fTY = 0.0f;
glTexCoord2f(fTX, fTY);
glVertex3f(vV1.fX, vV1.fY, vV1.fZ);
vVerNear = vV2-vNearest;
fTX = (float) (vVerNear.DotProduct(vPolygonHorizontal*fScale)+0.5f);
if(fTX > 1.0f)
fTX = 1.0f;
if(fTX < 0.0f)
fTX = 0.0f;
fTY = (float) (vVerNear.DotProduct(vPolygonVertical*fScale)+0.5f);
if(fTY > 1.0f)
fTY = 1.0f;
if(fTY < 0.0f)
fTY = 0.0f;
glTexCoord2f(fTX, fTY);
glVertex3f(vV2.fX, vV2.fY, vV2.fZ);
vVerNear = vV3-vNearest;
fTX = (float) (vVerNear.DotProduct(vPolygonHorizontal*fScale)+0.5f);
if(fTX > 1.0f)
fTX = 1.0f;
if(fTX < 0.0f)
fTX = 0.0f;
fTY = (float) (vVerNear.DotProduct(vPolygonVertical*fScale)+0.5f);
if(fTY > 1.0f)
fTY = 1.0f;
if(fTY < 0.0f)
fTY = 0.0f;
glTexCoord2f(fTX, fTY);
glVertex3f(vV3.fX, vV3.fY, vV3.fZ);
} // end AS_DLIGHT::Light()