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()