/* ------------------------------------------------------------------------------------ */
int CCameraManager::GetPosition(geVec3d *thePosition)
{
// changed RF063
	geXForm3d theViewPoint;

// changed QD 12/15/05
	//geXForm3d_SetIdentity(&theViewPoint); // Clear the matrix
	//geXForm3d_RotateZ(&theViewPoint, Rotation.Z); // Rotate then translate
	geXForm3d_SetZRotation(&theViewPoint, Rotation.Z);
// end change
	geXForm3d_RotateX(&theViewPoint, Rotation.X);
	geXForm3d_RotateY(&theViewPoint, Rotation.Y);

	geXForm3d_Translate(&theViewPoint, Translation.X, Translation.Y,
		Translation.Z);

	if(jerk)
	{
		geVec3d Direction;
		geXForm3d_GetIn(&theViewPoint, &Direction);
		geVec3d_AddScaled(&theViewPoint.Translation, &Direction, -jerkamt, &theViewPoint.Translation);
	}

	//*thePosition = Translation;
	*thePosition = theViewPoint.Translation;
// end change RF063
	return RGF_SUCCESS;
}
Example #2
0
//========================================================================================
//	geCamera_ScreenPointToWorld
//========================================================================================
GENESISAPI void GENESISCC geCamera_ScreenPointToWorld (	const geCamera	*Camera,
														int32			 ScreenX,
														int32			 ScreenY,
														geVec3d			*Vector)
// Takes a screen X and Y pair, and a camera and generates a vector pointing
// in the direction from the camera position to the screen point.
{
	geVec3d In,Left,Up;
	geVec3d ScaledIn,ScaledLeft,ScaledUp ;
	geFloat	XCenter ;
	geFloat	YCenter ;
	geFloat	Scale ;
	const geXForm3d *pM;

	pM = &(Camera->TransposeXForm);
	XCenter = Camera->XCenter ;
	YCenter = Camera->YCenter ;
	Scale   = Camera->Scale ;

	geXForm3d_GetIn( pM, &In ) ;
	geXForm3d_GetLeft( pM, &Left ) ;
	geXForm3d_GetUp( pM, &Up ) ;
	
	geVec3d_Scale(&In,   Scale, &ScaledIn);
	geVec3d_Scale(&Left, XCenter - ((geFloat)ScreenX), &ScaledLeft );
	geVec3d_Scale(&Up,   YCenter - ((geFloat)ScreenY), &ScaledUp   );

	geVec3d_Copy(&ScaledIn, Vector);
	geVec3d_Add(Vector,		&ScaledLeft,	Vector );
	geVec3d_Add(Vector,		&ScaledUp,		Vector );
	geVec3d_Normalize(Vector);
}
/* ------------------------------------------------------------------------------------ */
int CCameraManager::RenderView()
{
	geXForm3d theViewPoint;

// changed QD 12/15/05
	//geXForm3d_SetIdentity(&theViewPoint); // Clear the matrix
	//geXForm3d_RotateZ(&theViewPoint, Rotation.Z); // Rotate then translate
	geXForm3d_SetZRotation(&theViewPoint, Rotation.Z);
// end change
	geXForm3d_RotateX(&theViewPoint, Rotation.X);
	geXForm3d_RotateY(&theViewPoint, Rotation.Y);

	geXForm3d_Translate(&theViewPoint, Translation.X+shakex, Translation.Y+shakey, Translation.Z);

// changed RF063
	GE_Contents ZoneContents;
	geExtBox ExtBox;
	geVec3d Direction, Pos;
	GE_LVertex	Vertex;

	ExtBox.Min.X = ExtBox.Min.Z = -1.0f;
	ExtBox.Min.Y = 0.0f;
	ExtBox.Max.Y = 1.0f;
	ExtBox.Max.X = ExtBox.Max.Z = 1.0f;

	if(CCD->Collision()->GetContentsOf(Translation, &ExtBox, &ZoneContents) == RGF_SUCCESS)
	//if(geWorld_GetContents(CCD->World(), &Translation, &ExtBox.Min,
		//&ExtBox.Max, GE_COLLIDE_MODELS, 0, NULL, NULL, &ZoneContents) == GE_TRUE)
	{
		Liquid * LQ = CCD->Liquids()->IsLiquid(ZoneContents.Model);

		if(LQ)
		{
			geXForm3d_GetIn(&theViewPoint, &Direction);
			geVec3d_AddScaled(&Translation, &Direction, OverlayDist, &Pos);

			Vertex.r = LQ->TintColor.r;
			Vertex.g = LQ->TintColor.g;
			Vertex.b = LQ->TintColor.b;
			Vertex.a = LQ->Transparency;

			Vertex.u = 0.0f;
			Vertex.v = 0.0f;

			Vertex.X = Pos.X;
			Vertex.Y = Pos.Y;
			Vertex.Z = Pos.Z;

			geWorld_AddPolyOnce(CCD->World(), &Vertex, 1,
				LQ->Texture,
				GE_TEXTURED_POINT  , GE_RENDER_DO_NOT_OCCLUDE_SELF, 2.0f );
		}
// changed RF064
		else
		{
			Overlay * OL = CCD->Overlays()->IsOverlay(ZoneContents.Model);

			if(OL)
			{
				geXForm3d_GetIn(&theViewPoint, &Direction);
				geVec3d_AddScaled(&Translation, &Direction, OverlayDist, &Pos);

				Vertex.r = OL->TintColor.r;
				Vertex.g = OL->TintColor.g;
				Vertex.b = OL->TintColor.b;
				Vertex.a = OL->Transparency;

				Vertex.u = 0.0f;
				Vertex.v = 0.0f;

				Vertex.X = Pos.X;
				Vertex.Y = Pos.Y;
				Vertex.Z = Pos.Z;

				geWorld_AddPolyOnce(CCD->World(), &Vertex, 1, OL->Texture,
					GE_TEXTURED_POINT  , GE_RENDER_DO_NOT_OCCLUDE_SELF, 2.0f);
			}
		}
// end change RF064
	}

	if(jerk)
	{
		geVec3d Direction;
		geXForm3d_GetIn(&theViewPoint, &Direction);
		geVec3d_AddScaled(&theViewPoint.Translation, &Direction, -jerkamt, &theViewPoint.Translation);
	}

// end change RF063
	//	Set up camera attributes just prior to rendering the world.

	geRect Rect;
	geCamera_SetWorldSpaceXForm(EngineCamera, &theViewPoint);
	geCamera_GetClippingRect(EngineCamera, &Rect);
	geCamera_SetAttributes(EngineCamera, FOV, &Rect);
// changed RF064
	geVec3d_Subtract(&m_OldXForm.Translation, &theViewPoint.Translation, &m_vMoveDif );
	m_bPositionMoved = !geVec3d_IsZero(&m_vMoveDif);

	if( m_bPositionMoved  ||
		m_OldXForm.AX != theViewPoint.AX || m_OldXForm.AY != theViewPoint.AY || m_OldXForm.AZ != theViewPoint.AZ ||
		m_OldXForm.BX != theViewPoint.BX || m_OldXForm.BY != theViewPoint.BY || m_OldXForm.BZ != theViewPoint.BZ ||
		m_OldXForm.CX != theViewPoint.CX || m_OldXForm.CY != theViewPoint.CY || m_OldXForm.CZ != theViewPoint.CZ)
	{
		m_bViewChanged = true;
		m_OldXForm = theViewPoint;
	}
// end change RF064

	return RGF_SUCCESS;
}
/* ------------------------------------------------------------------------------------ */
void CCameraManager::DoIsoTracking()
{
	geXForm3d theViewPoint;
	geVec3d Pos;
	GE_Collision Collision;
	geVec3d Front, Back;
	geVec3d Direction;
	geFloat CurrentDistance;
	geExtBox ActorExtBox;
	geFloat ActorScale;
	geVec3d Orient;
	geFloat x;

	CCD->ActorManager()->GetScale(theActor, &ActorScale);		// Get actor scale
	CCD->ActorManager()->GetBoundingBox(theActor, &ActorExtBox);
	CurrentDistance = m_defaultdistance * ActorScale;

	geVec3d ActorPosition, ActorRotation;
	CCD->ActorManager()->GetPosition(theActor, &ActorPosition);
	ActorPosition.Y += CameraOffsetTranslation.Y;
	CCD->ActorManager()->GetRotation(theActor, &ActorRotation);
	ActorRotation.X = 0.0f;

// changed QD 12/15/05
	//geXForm3d_SetIdentity(&theViewPoint);
	//geXForm3d_RotateZ(&theViewPoint, CameraOffsetRotation.Z);
	geXForm3d_SetZRotation(&theViewPoint, CameraOffsetRotation.Z);
// end change
	geXForm3d_RotateX(&theViewPoint, CameraOffsetRotation.X+GE_PIOVER180*(m_cameraX));
	geXForm3d_RotateY(&theViewPoint, CameraOffsetRotation.Y+GE_PIOVER180*(m_cameraY));
	geXForm3d_Translate(&theViewPoint, ActorPosition.X, ActorPosition.Y, ActorPosition.Z);

	Pos = theViewPoint.Translation;
	geXForm3d_GetIn(&theViewPoint, &Direction);
	geVec3d_AddScaled(&Pos, &Direction, CurrentDistance, &Back);
// changed QD 12/15/05
	// geVec3d_AddScaled(&Pos, &Direction, 0.0f, &Front);
	geVec3d_Copy(&Pos, &Front);
// end change

	if(IsoCollFlag)
	{
		if(geWorld_Collision(CCD->World(), &CameraExtBox.Min, &CameraExtBox.Max, &Front,
		&Back, /*GE_VISIBLE_CONTENTS*/GE_CONTENTS_SOLID_CLIP, GE_COLLIDE_ALL, 0, NULL, NULL, &Collision))
		{
// changed QD 01/2004
			// can't be negative (sqrt)
			// CurrentDistance = (geFloat)fabs(geVec3d_DistanceBetween(&Collision.Impact, &Front));
			// if(CurrentDistance < 0.0f)
			//	CurrentDistance = 0.0f;
			CurrentDistance = geVec3d_DistanceBetween(&Collision.Impact, &Front);
// end change

			if(CurrentDistance > (m_defaultdistance*ActorScale))
				CurrentDistance = m_defaultdistance*ActorScale;

			geVec3d_AddScaled(&Pos, &Direction, CurrentDistance, &Back);
		}

// changed QD 01/2004
		if(CCD->Meshes()->CollisionCheck(&CameraExtBox.Min, &CameraExtBox.Max, Front, Back, &Collision))
		{
			geFloat CurrentDistance2 = geVec3d_DistanceBetween(&Collision.Impact, &Front);

			if(CurrentDistance2 > (m_defaultdistance*ActorScale))
				CurrentDistance2 = m_defaultdistance*ActorScale;

			if(CurrentDistance2<CurrentDistance)
			{
				CurrentDistance = CurrentDistance2;
				geVec3d_AddScaled(&Pos, &Direction, CurrentDistance2, &Back);
			}
		}
// end change
	}

	m_currentdistance = CurrentDistance/ActorScale;

	if(IsoCollFlag)
	{
		geFloat fAlpha = 255.0f;

		if(CurrentDistance < (40.0f*ActorScale))
		{
			fAlpha = (10.0f*((CurrentDistance-((geFloat)fabs(ActorExtBox.Min.Z)+1.0f))/ActorScale))+30.0f;

			if(fAlpha < (15.0f*ActorScale))
				fAlpha = 0.0f;

			if(fAlpha > 255.0f)
				fAlpha = 255.0f;
		}

		CCD->ActorManager()->SetAlpha(theActor, fAlpha);			// Adjust actor alpha
	}

	geVec3d_Subtract( &Pos, &Back, &Orient );

	// protect from Div by Zero
	if(CurrentDistance > 0.0f)
	{
		x = Orient.X;
		// changed QD 12/15/05
		// Orient.X = GE_PI*0.5f - (geFloat)acos(Orient.Y / CurrentDistance);
		Orient.X = GE_PIOVER2 - (geFloat)acos(Orient.Y / CurrentDistance);
		Orient.Y = (geFloat)atan2(x, Orient.Z) + GE_PI;
		Orient.Z = 0.0f;	// roll is zero - always!!?

	}

	Rotation = Orient;										// Set camera orientation
	Translation = Back;										// Set camera translation

	return;
}
/* ------------------------------------------------------------------------------------ */
void CCameraManager::DoThirdPersonTracking()
{
	geXForm3d theViewPoint;
	geVec3d Pos;
	GE_Collision Collision;
	geVec3d Front, Back;
	geVec3d Direction;
	geFloat CurrentDistance;
	geExtBox ActorExtBox;
	geFloat ActorScale;
	geVec3d Orient;
	geFloat x;
// changed QD 01/2004
	geFloat PlayerScale = CCD->Player()->GetScale();
// end change

	CCD->ActorManager()->GetScale(theActor, &ActorScale);		// Get actor scale
	CCD->ActorManager()->GetBoundingBox(theActor, &ActorExtBox);
	CurrentDistance = m_defaultdistance * ActorScale;

	geVec3d ActorPosition, ActorRotation;
	CCD->ActorManager()->GetPosition(theActor, &ActorPosition);
	ActorPosition.Y += CameraOffsetTranslation.Y;
	CCD->ActorManager()->GetRotation(theActor, &ActorRotation);
// Start Nov2003DCS
	geVec3d_Add(&ActorRotation, &CameraOffsetRotation, &ActorRotation);
// End Nov2003DCS
	ActorRotation.X = 0.0f;

// changed QD 12/15/05
	//geXForm3d_SetIdentity(&theViewPoint);
	//geXForm3d_RotateZ(&theViewPoint, ActorRotation.Z+CameraOffsetRotation.Z);
	geXForm3d_SetZRotation(&theViewPoint, ActorRotation.Z+CameraOffsetRotation.Z);
// end change
	geXForm3d_RotateX(&theViewPoint, ActorRotation.X+CameraOffsetRotation.X+GE_PIOVER180*(m_cameraX));
	geXForm3d_RotateY(&theViewPoint, ActorRotation.Y+CameraOffsetRotation.Y+GE_PIOVER180*(m_cameraY));
	geXForm3d_Translate(&theViewPoint, ActorPosition.X, ActorPosition.Y, ActorPosition.Z);

	Pos = theViewPoint.Translation;
	geXForm3d_GetIn(&theViewPoint, &Direction);
	geVec3d_AddScaled(&Pos, &Direction, CurrentDistance, &Back);
// changed QD 12/15/05
	// geVec3d_AddScaled(&Pos, &Direction, 0.0f, &Front);
	geVec3d_Copy(&Pos, &Front);
// end change

	if(geWorld_Collision(CCD->World(), &CameraExtBox.Min, &CameraExtBox.Max, &Front,
		&Back, /*GE_VISIBLE_CONTENTS*/GE_CONTENTS_SOLID_CLIP, GE_COLLIDE_ALL, 0, NULL, NULL, &Collision))
    {
// changed QD 01/2004
		// can't be negative (sqrt!)
		// CurrentDistance = (geFloat)fabs(geVec3d_DistanceBetween(&Collision.Impact, &Front));
		// if(CurrentDistance < 0.0f)
		//	CurrentDistance = 0.0f;
		CurrentDistance = geVec3d_DistanceBetween(&Collision.Impact, &Front);
// end change

		if(CurrentDistance > (m_defaultdistance*ActorScale))
			CurrentDistance = m_defaultdistance*ActorScale;

		geVec3d_AddScaled(&Pos, &Direction, CurrentDistance, &Back);
	}

// changed QD 01/2004
	geVec3d_AddScaled(&Pos, &Direction, playermindistance*ActorScale, &Front);

	if(CCD->Meshes()->CollisionCheck(&CameraExtBox.Min, &CameraExtBox.Max, Front, Back, &Collision))
	{
// changed QD distance can't be negative
	//	geFloat CurrentDistance2 = (geFloat)fabs(geVec3d_DistanceBetween(&Collision.Impact, &Front));//-4.0f;
		geFloat CurrentDistance2 = geVec3d_DistanceBetween(&Collision.Impact, &Front);

		CurrentDistance2 += playermindistance*ActorScale;

		if(theActor == CCD->Player()->GetActor())
		{
			if(CurrentDistance2 < (playermindistance*ActorScale))
				CurrentDistance2 = playermindistance*ActorScale;
			if(CurrentDistance2 > (playermaxdistance*ActorScale))
				CurrentDistance2 = playermaxdistance*ActorScale;
		}
		else
		{
			if(CurrentDistance2 > (m_defaultdistance*ActorScale))
				CurrentDistance2 = m_defaultdistance*ActorScale;
		}

		if(CurrentDistance2 < CurrentDistance)
		{
			CurrentDistance = CurrentDistance2;
			geVec3d_AddScaled(&Pos, &Direction, CurrentDistance2, &Back);
		}
	}
// end change

	m_currentdistance = CurrentDistance/ActorScale;

	// Ok, here's the implementation of Ralph Deane's too-cool
	// ..third-person Actor Fading code. As the camera approaches
	// ..the player avatar, the AVATAR IS FADED OUT until finally
	// ..it's rendering is shut down. This is one Way Cool Effect.
	// 03/22/2000 eaa3 Added Ralph Deane's scaling fixes.

	geFloat fAlpha = 255.0f;

	if(CurrentDistance < (40.0f*ActorScale))
	{
		fAlpha = (10.0f*((CurrentDistance-((geFloat)fabs(ActorExtBox.Min.Z)+1.0f))/ActorScale))+30.0f;

		if(fAlpha < (15.0f*ActorScale))
			fAlpha = 0.0f;

		if(fAlpha > 255.0f)
			fAlpha = 255.0f;
	}

	CCD->ActorManager()->SetAlpha(theActor, fAlpha);			// Adjust actor alpha

	geVec3d_Subtract( &Pos, &Back, &Orient );

	// protect from Div by Zero
	if(CurrentDistance > 0.0f)
	{
		x = Orient.X;
		// changed QD 12/15/05
		// Orient.X = (geFloat)( GE_PI*0.5 ) - (geFloat)acos(Orient.Y / CurrentDistance);
		Orient.X = GE_PIOVER2 - (geFloat)acos(Orient.Y / CurrentDistance);
		Orient.Y = (geFloat)atan2(x, Orient.Z) + GE_PI;
		Orient.Z = 0.0f;	// roll is zero - always!!?
	}

	Rotation = Orient;										// Set camera orientation
	Translation = Back;										// Set camera translation

	return;
}