Beispiel #1
0
//---------------------------------------------------------------------------
void Terrain::geometry (void)
{
	//---------------------------------------------------------------------
	leastZ = 1.0f;leastW = 1.0f;
	mostZ = -1.0f; mostW = -1.0;
	leastWY = 0.0f; mostWY = 0.0f;

	//-----------------------------------
	// Transform entire list of vertices
	VertexPtr currentVertex = vertexList;

	Stuff::Vector3D cameraPos;
	cameraPos.x = -eye->getCameraOrigin().x;
	cameraPos.y = eye->getCameraOrigin().z;
	cameraPos.z = eye->getCameraOrigin().y;

	float vClipConstant = eye->verticalSphereClipConstant;
	float hClipConstant = eye->horizontalSphereClipConstant; 
	
 	long i=0;
	for (i=0;i<numberVertices;i++)
	{
		//----------------------------------------------------------------------------------------
		// Figure out if we are in front of camera or not.  Should be faster then actual project!
		// Should weed out VAST overwhelming majority of vertices!
		bool onScreen = false;
	
		//-----------------------------------------------------------------
		// Find angle between lookVector of Camera and vector from camPos
		// to Target.  If angle is less then halfFOV, object is visible.
		if (eye->usePerspective)
		{
			//-------------------------------------------------------------------
			//NEW METHOD from the WAY BACK Days
			onScreen = true;
			
			Stuff::Vector3D vPosition;
			vPosition.x = currentVertex->vx;
			vPosition.y = currentVertex->vy;
			vPosition.z = currentVertex->pVertex->elevation;
  
			Stuff::Vector3D objectCenter;
			objectCenter.Subtract(vPosition,cameraPos);
			Camera::cameraFrame.trans_to_frame(objectCenter);
			float distanceToEye = objectCenter.GetApproximateLength();

			Stuff::Vector3D clipVector = objectCenter;
			clipVector.z = 0.0f;
			float distanceToClip = clipVector.GetApproximateLength();
			float clip_distance = fabs(1.0f / objectCenter.y);
			
			if (distanceToClip > CLIP_THRESHOLD_DISTANCE)
			{
				//Is vertex on Screen OR close enough to screen that its triangle MAY be visible?
				// WE have removed the atans here by simply taking the tan of the angle we want above.
				float object_angle = fabs(objectCenter.z) * clip_distance;
				float extent_angle = VERTEX_EXTENT_RADIUS / distanceToEye;
				if (object_angle > (vClipConstant + extent_angle))
				{
					//In theory, we would return here.  Object is NOT on screen.
					onScreen = false;
				}
				else
				{
					object_angle = fabs(objectCenter.x) * clip_distance;
					if (object_angle > (hClipConstant + extent_angle))
					{
						//In theory, we would return here.  Object is NOT on screen.
						onScreen = false;
					}
				}
			}
			
			if (onScreen)
			{
				if (distanceToEye > Camera::MaxClipDistance)
				{
					currentVertex->hazeFactor = 1.0f;
				}
				else if (distanceToEye > Camera::MinHazeDistance)
				{
					currentVertex->hazeFactor = (distanceToEye - Camera::MinHazeDistance) * Camera::DistanceFactor;
				}
				else
				{
					currentVertex->hazeFactor = 0.0f;
				}
				
				//---------------------------------------
				// Vertex is at edge of world or beyond.
				Stuff::Vector3D vPos(currentVertex->vx,currentVertex->vy,currentVertex->pVertex->elevation);
				bool isVisible = Terrain::IsGameSelectTerrainPosition(vPos) || drawTerrainGrid;
				if (!isVisible)
				{
					currentVertex->hazeFactor = 1.0f;
					onScreen = true;
				}
			}
			else
			{
				currentVertex->hazeFactor = 1.0f;
			}
		}
		else
		{
			currentVertex->hazeFactor = 0.0f;
			onScreen = true;
		}

		bool inView = false;
		Stuff::Vector4D screenPos(-10000.0f,-10000.0f,-10000.0f,-10000.0f);
		if (onScreen)
		{
			Stuff::Vector3D vertex3D(currentVertex->vx,currentVertex->vy,currentVertex->pVertex->elevation);
			inView = eye->projectZ(vertex3D,screenPos);
		
			currentVertex->px = screenPos.x;
			currentVertex->py = screenPos.y;
			currentVertex->pz = screenPos.z;
			currentVertex->pw = screenPos.w;
			
			//----------------------------------------------------------------------------------
			//We must transform these but should NOT draw any face where all three are fogged. 
//			if (currentVertex->hazeFactor == 1.0f)		
//				onScreen = false;
		}
		else
		{
			currentVertex->px = currentVertex->py = 10000.0f;
			currentVertex->pz = -0.5f;
			currentVertex->pw = 0.5f;
			currentVertex->hazeFactor = 0.0f;
		}	
		
		//------------------------------------------------------------
		// Fix clip.  Vertices can all be off screen and triangle
		// still needs to be drawn!
		if (eye->usePerspective && Environment.Renderer != 3)
		{
			currentVertex->clipInfo = onScreen;
		}
		else
			currentVertex->clipInfo = inView;
		
		if (currentVertex->clipInfo)				//ONLY set TRUE ones.  Otherwise we just reset the FLAG each vertex!
		{
			setObjBlockActive(currentVertex->getBlockNumber(), true);
			setObjVertexActive(currentVertex->vertexNum,true);
			
			if (inView)
			{
				if (screenPos.z < leastZ)
				{
					leastZ = screenPos.z;
				}
				
				if (screenPos.z > mostZ)
				{
					mostZ = screenPos.z;
				}
				
				if (screenPos.w < leastW)
				{
					leastW = screenPos.w;
					leastWY = screenPos.y;
				}
				
				if (screenPos.w > mostW)
				{
					mostW = screenPos.w;
					mostWY = screenPos.y;
				}
			}
		}

		currentVertex++;
	}
	
	//-----------------------------------
	// setup terrain quad textures
	// Also sets up mine data.
	TerrainQuadPtr currentQuad = quadList;
	for (i=0;i<numberQuads;i++)
	{
		currentQuad->setupTextures();
		currentQuad++;
	}

	float ywRange = 0.0f, yzRange = 0.0f;
	if (fabs(mostWY - leastWY) > Stuff::SMALL)
	{
		ywRange = (mostW - leastW) / (mostWY - leastWY);
		yzRange = (mostZ - leastZ) / (mostWY - leastWY);
	}

	eye->setInverseProject(mostZ,leastW,yzRange,ywRange);

	//-----------------------------------
	// update the cloud layer
	if (Terrain::cloudLayer)
		Terrain::cloudLayer->update();
}
Beispiel #2
0
//---------------------------------------------------------------------------
void Clouds::update (void)
{
	renderClouds = false;
	
	scrollU += frameLength * SCROLL_U_FACTOR;
	scrollV += frameLength * SCROLL_V_FACTOR;

	if (scrollU > 1.0f)
		scrollU -= 1.0f;
		
	if (scrollV > 1.0f)
		scrollV -= 1.0f;
		
	if (scrollU < -1.0f)
		scrollU += 1.0f;
		
	if (scrollV < -1.0f)
		scrollV += 1.0f;
		
	//---------------------------------------------------------------------
	// If projectionAngle is less then some magic number, draw the clouds.
	// Otherwise, do not do anything!
	if (eye->active && eye->usePerspective && (eye->getProjectionAngle() < MAX_CLOUDS_ANGLE))
	{
		//renderClouds = true;
		
		//-------------------------------------------------------
		// Create the cloud grid based on camera CENTER position.
		Stuff::Vector3D centerPosition(eye->getPosition());
		
		//-------------------------------------------------------
		// Create a topLeft vertex
		float tLeftX = centerPosition.x + MAX_CLOUDS_SIZE;
		float tLeftY = centerPosition.y + MAX_CLOUDS_SIZE;
		
		//-------------------------------------------------------
		// Create the grid.
		long cloudInc = float2long(MAX_CLOUDS_SIZE * 2.0f / gridSize);
		float uvInc = MAX_UV_REPEAT / float(gridSize);
		
		for (long y=0;y<gridSize;y++)
		{
			for (long x=0;x<gridSize;x++)
			{
				cloudVertices[x + (y*gridSize)].vx = tLeftX - (cloudInc * x);
				cloudVertices[x + (y*gridSize)].vy = tLeftY - (cloudInc * y);
				
				cloudVertices[x + (y*gridSize)].pu = CLOUD_START_U + (uvInc * x);
				cloudVertices[x + (y*gridSize)].pv = CLOUD_START_V + (uvInc * y);
 			}
		}
		
		//-------------------------------------------------------
		// Transform Grid
		long gridTotal = gridSize * gridSize;
		for (long i=0;i<gridTotal;i++)
		{
			//----------------------------------------------------------------------------------------
			// Figure out if we are in front of camera or not.  Should be faster then actual project!
			// Should weed out VAST overwhelming majority of vertices!
			bool onScreen = true;
		
			//-----------------------------------------------------------------
			// Find angle between lookVector of Camera and vector from camPos
			// to Target.  If angle is less then halfFOV, object is visible.
			
			//-------------------------------------------------------------------
			// Then figure out if FarClipped.  Should weed out a boatload more!
			float hazeFactor = 0.0f;
			Stuff::Point3D Distance;
			Stuff::Point3D vPosition;
			Stuff::Point3D eyePosition(eye->getPosition());
			vPosition.x = cloudVertices[i].vx;;
			vPosition.y = cloudVertices[i].vy;
			vPosition.z = centerPosition.z;
				
			Distance.Subtract(eyePosition,vPosition);
			float eyeDistance = Distance.GetApproximateLength();
			if (eyeDistance > Camera::MaxClipDistance)
			{
				hazeFactor = 1.0f;
				//onScreen = false;
			}
			else if (eyeDistance > Camera::MinHazeDistance)
			{
				hazeFactor = (eyeDistance - Camera::MinHazeDistance) * Camera::DistanceFactor;
			}
			else
			{
				hazeFactor = 0.0f;
			}
					
			//------------------------------------------------------------
			// Calculate the HazeDWORD here
			if (hazeFactor != 0.0f)
			{
				float fogFactor = 1.0 - hazeFactor;
				DWORD distFog = float2long(fogFactor * 255.0f);
				
				cloudVertices[i].fogRGB = (distFog<<24) + (0xffffff);
			}
			else
			{
				cloudVertices[i].fogRGB = 0xffffffff;
			}
			
			if (onScreen)
			{
				Stuff::Vector3D Distance;
				Stuff::Point3D objPosition;
				Stuff::Point3D eyePosition(eye->getCameraOrigin());
				objPosition.x = -cloudVertices[i].vx;
				objPosition.y = CLOUD_ALTITUDE;
				objPosition.z = cloudVertices[i].vy;
			
				Distance.Subtract(objPosition,eyePosition);
				Distance.Normalize(Distance);
					
				float cosine = Distance * eye->getLookVector();
				if (cosine > eye->cosHalfFOV)
					onScreen = true;
				else
					onScreen = false;
			}
			else
			{
				hazeFactor = 1.0f;
			}
			
			Stuff::Vector3D vertex3D(cloudVertices[i].vx,cloudVertices[i].vy,(CLOUD_ALTITUDE+eye->getCameraOrigin().y));
			Stuff::Vector4D screenPos;
			bool inView = eye->projectZ(vertex3D,screenPos);
			
			cloudVertices[i].px = screenPos.x;
			cloudVertices[i].py = screenPos.y;
			cloudVertices[i].pz = screenPos.z;
			cloudVertices[i].pw = screenPos.w;
			
			//------------------------------------------------------------
			// Fix clip.  Vertices can all be off screen and triangle
			// still needs to be drawn!
			cloudVertices[i].clipInfo = onScreen && inView;
			
			//------------------------------------------------------------
			// Still need to scrollUVs here!
			cloudVertices[i].pu += scrollU;
			cloudVertices[i].pv += scrollV;
		}
		
		for (y=0;y<(gridSize-1);y++)
		{
			for (long x=0;x<(gridSize-1);x++)
			{
				CloudVertexPtr cloudVertex0 = &(cloudVertices[x     + (y    *gridSize)]);
				CloudVertexPtr cloudVertex1 = &(cloudVertices[(x+1) + (y    *gridSize)]); 
				CloudVertexPtr cloudVertex2 = &(cloudVertices[(x+1) + ((y+1)*gridSize)]); 
				CloudVertexPtr cloudVertex3 = &(cloudVertices[x     + ((y+1)*gridSize)]); 
				
				bool clipCheck = (cloudVertex0->clipInfo || cloudVertex1->clipInfo || cloudVertex2->clipInfo);
				if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
									(cloudVertex1->pz < 1.0f) && (cloudVertex1->pz > 0.0f) && 
									(cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f)))
				{
					mcTextureManager->addTriangle(mcTextureNodeIndex,MC2_DRAWALPHA);
				}
				
				clipCheck = (cloudVertex0->clipInfo || cloudVertex2->clipInfo || cloudVertex3->clipInfo);
				if (clipCheck && ((cloudVertex0->pz < 1.0f) && (cloudVertex0->pz > 0.0f) &&
									(cloudVertex2->pz < 1.0f) && (cloudVertex2->pz > 0.0f) && 
									(cloudVertex3->pz < 1.0f) && (cloudVertex3->pz > 0.0f)))
				{
					mcTextureManager->addTriangle(mcTextureNodeIndex,MC2_DRAWALPHA);
				}
			}
		}			 
	}
}