Esempio n. 1
0
void SpinningWorldModel::UpdateOn( const double &fCurTime )
{
	LTVector	vNewPos(0.0f, 0.0f, 0.0f);
	LTRotation	rNewRot;
	float		fDeltaTm = (float)(fCurTime - m_fLastTime);
	float		fPercent = 0.0f;
	LTVector	vOldAngles( m_fPitch, m_fYaw, m_fRoll );

	m_bUpdateSpin = true;

	if( m_vVelocity.x )
	{
		m_fPitch += m_vVelocity.x * fDeltaTm;
	}

	if( m_vVelocity.y )
	{
		m_fYaw += m_vVelocity.y * fDeltaTm;
	}

	if( m_vVelocity.z )
	{
		m_fRoll += m_vVelocity.z * fDeltaTm;
	}

	float	fDifLeft = (m_vInitOnAngles - LTVector( m_fPitch, m_fYaw, m_fRoll )).Mag();
	float	fFinalDif = (m_vInitOnAngles - m_vInitOffAngles).Mag();
		
	// Get the percent of our rotation to use for the light ani...

	fPercent = ( fFinalDif > MATH_EPSILON ? 1 - fDifLeft / fFinalDif : 1.0f );

	uint32 nFlags;
	g_pCommonLT->GetObjectFlags( m_hObject, OFT_Flags, nFlags );
	bool bTestCollisions = !!( nFlags & FLAG_SOLID );

	if( !CalculateNewPosRot( vNewPos, rNewRot, m_vOnPos, m_fPowerOnTime, fPercent, bTestCollisions ) && !(m_dwPropFlags & AWM_PROP_FORCEMOVE) )
	{
		// Restore our angles...

		m_fPitch	= vOldAngles.x;
		m_fYaw		= vOldAngles.y;
		m_fRoll		= vOldAngles.z;

		m_fMoveStartTm	+= g_pLTServer->GetFrameTime();
		m_fLastTime		= fCurTime;
		m_bUpdateSpin	= false;

		return;
	}

	g_pLTServer->Physics()->MoveObject( m_hObject, vNewPos, 0 );

	// Check to see if we actually moved anywhere...

	LTVector	vPos;
	g_pLTServer->GetObjectPos( m_hObject, &vPos );
	if( !vPos.NearlyEquals( vNewPos, MATH_EPSILON ) )
	{
		// Restore our angles...

		m_fPitch	= vOldAngles.x;
		m_fYaw		= vOldAngles.y;
		m_fRoll		= vOldAngles.z;

		m_fMoveStartTm	+= g_pLTServer->GetFrameTime();
		m_fLastTime		= fCurTime;
		m_bUpdateSpin	= false;

		return;
	}

	g_pLTServer->RotateObject( m_hObject, rNewRot );

	// Keep the Pitch, Yaw and Roll within 2PI so they will never over flow...

	if( m_fPitch > MATH_CIRCLE )
	{
		m_fPitch = -(MATH_CIRCLE - m_fPitch);
	}
	else if( m_fPitch < -MATH_CIRCLE )
	{
		m_fPitch += MATH_CIRCLE;
	}

	if( m_fYaw > MATH_CIRCLE )
	{
		m_fYaw = -(MATH_CIRCLE - m_fYaw);
	}
	else if( m_fYaw < -MATH_CIRCLE )
	{
		m_fYaw += MATH_CIRCLE;
	}

	if( m_fRoll > MATH_CIRCLE )
	{
		m_fRoll = -(MATH_CIRCLE - m_fRoll);
	}
	else if( m_fRoll < -MATH_CIRCLE )
	{
		m_fRoll += MATH_CIRCLE;
	}

	m_fLastTime = fCurTime;
}
Esempio n. 2
0
void SpinningWorldModel::UpdateOn( const LTFLOAT &fCurTime )
{
	LTVector	vNewPos(0.0f, 0.0f, 0.0f);
	LTRotation	rNewRot;
	LTFLOAT		fDeltaTm = fCurTime - m_fLastTime;
	LTFLOAT		fPercent = 0.0f;
	LTVector	vOldAngles( m_fPitch, m_fYaw, m_fRoll );

	m_bUpdateSpin = LTTRUE;

	if( m_vVelocity.x )
	{
		m_fPitch += m_vVelocity.x * fDeltaTm;
	}

	if( m_vVelocity.y )
	{
		m_fYaw += m_vVelocity.y * fDeltaTm;
	}

	if( m_vVelocity.z )
	{
		m_fRoll += m_vVelocity.z * fDeltaTm;
	}

	LTFLOAT	fDifLeft = (m_vOnAngles - LTVector( m_fPitch, m_fYaw, m_fRoll )).Mag();
	LTFLOAT	fFinalDif = (m_vOnAngles - m_vOffAngles).Mag();
		
	// Get the percent of our rotation to use for the light ani...

	fPercent = ( fFinalDif > MATH_EPSILON ? 1 - fDifLeft / fFinalDif : 1.0f );

	if( !CalculateNewPosRot( vNewPos, rNewRot, m_vOnPos, m_fPowerOnTime, fPercent, LTTRUE ) && !(m_dwPropFlags & AWM_PROP_FORCEMOVE) )
	{
		// Restore our angles...

		m_fPitch	= vOldAngles.x;
		m_fYaw		= vOldAngles.y;
		m_fRoll		= vOldAngles.z;

		m_fMoveStartTm	+= g_pLTServer->GetFrameTime();
		m_fLastTime		= fCurTime;
		m_bUpdateSpin	= LTFALSE;

		return;
	}

	g_pLTServer->MoveObject( m_hObject, &vNewPos );

	// Check to see if we actually moved anywhere...

	LTVector	vPos;
	g_pLTServer->GetObjectPos( m_hObject, &vPos );
	if( !vPos.NearlyEquals( vNewPos, MATH_EPSILON ) )
	{
		// Restore our angles...

		m_fPitch	= vOldAngles.x;
		m_fYaw		= vOldAngles.y;
		m_fRoll		= vOldAngles.z;

		m_fMoveStartTm	+= g_pLTServer->GetFrameTime();
		m_fLastTime		= fCurTime;
		m_bUpdateSpin	= LTFALSE;

		return;
	}

	g_pLTServer->RotateObject( m_hObject, &rNewRot );

	// Keep the Pitch, Yaw and Roll within 2PI so they will never over flow...

	if( m_fPitch > MATH_CIRCLE )
	{
		m_fPitch = -(MATH_CIRCLE - m_fPitch);
	}
	else if( m_fPitch < -MATH_CIRCLE )
	{
		m_fPitch += MATH_CIRCLE;
	}

	if( m_fYaw > MATH_CIRCLE )
	{
		m_fYaw = -(MATH_CIRCLE - m_fYaw);
	}
	else if( m_fYaw < -MATH_CIRCLE )
	{
		m_fYaw += MATH_CIRCLE;
	}

	if( m_fRoll > MATH_CIRCLE )
	{
		m_fRoll = -(MATH_CIRCLE - m_fRoll);
	}
	else if( m_fRoll < -MATH_CIRCLE )
	{
		m_fRoll += MATH_CIRCLE;
	}

	m_fLastTime = fCurTime;
}
Esempio n. 3
0
void ModelDraw::SetupModelLight(ModelInstance* pInstance, const ModelHookData& HookData, CRelevantLightList& LightList)
{
	//setup our light list information
	uint32 nMaxLights = LTMIN((uint32)g_CV_MaxModelLights, MAX_LIGHTS_SUPPORTED_BY_D3D);

	LTVector vInstancePosition;

	// Should we skip the root node and use it's first child node
	// for lighting consideration?
	if(g_CV_ModelLightingSkipRootNode)
	{
		// Index of the root node (should be 0)
		uint32 iRootNode = pInstance->NodeGetRootIndex();
		
		// How many children nodes does it have?
		uint32 iRootNodeNumKids = pInstance->NodeGetNumChildren( iRootNode );
		
		// Is there atleast one?
		if(iRootNodeNumKids > 0)
		{
		    // Just get the first one.
			// This assumes the the first child-node translates with the rest
			// of the mesh.
			uint32 iNode = pInstance->NodeGetChild( iRootNode, 0 );
			LTransform tf;
			pInstance->GetNodeTransform( iNode, tf, true );
		
			// Set our calculation position to the node's position
			vInstancePosition = tf.m_Pos;
		}
		else
		{
		    // If the root node doesn't have any children,
			// fall back to the root node's position.
			vInstancePosition = pInstance->GetPos();
		}
	}
	else // No? Then just use the root node position
	{
		//figure out the world position of this instance
		vInstancePosition = pInstance->GetPos();
	}

	LightList.ClearList();
	LightList.SetMaxLights(nMaxLights);
	LightList.SetObjectPos(vInstancePosition);
	LightList.SetObjectDims(pInstance->GetDims());

	// If they don't want lighting, set the values for no lighting and skip out
	if((g_CV_LightModels.m_Val == 0) || (HookData.m_ObjectFlags & FLAG_NOLIGHT))
	{
		LightList.AddAmbient(LTVector(255.0f, 255.0f, 255.0f));
		return;
	}

	//determine if we are in really close space
	bool bReallyClose = (HookData.m_ObjectFlags & FLAG_REALLYCLOSE) != 0;

	////////////////////////////////////////////////////////////////////
	// Add light from the environment.
	CRenderLight RenderLight;

	if(bReallyClose)
	{
		//this is really close, we need to transform it into the world
		g_ViewParams.m_mInvView.Apply(vInstancePosition);
	}

	// Global directional light dir.
	float fDirLightAmount = 0.0f;

	if (g_have_world && g_CV_ModelApplySun.m_Val && 
		(g_pStruct->m_GlobalLightColor.x || g_pStruct->m_GlobalLightColor.y || g_pStruct->m_GlobalLightColor.z))
	{
		// Use the previous lighting amount if it hasn't moved
		if ((pInstance->m_LastDirLightAmount >= 0.0f) &&
			(((pInstance->m_Flags2 & FLAG2_DYNAMICDIRLIGHT) == 0) ||
			(vInstancePosition.NearlyEquals(pInstance->m_LastDirLightPos, g_CV_ModelSunVariance.m_Val + 0.001f))))
		{
			fDirLightAmount = pInstance->m_LastDirLightAmount;
		}
		else
		{
			// Remember where we were last time we did this
			pInstance->m_LastDirLightPos = vInstancePosition;

			// Calculate the lighting
			fDirLightAmount = GetDirLightAmount(pInstance, vInstancePosition);

			// Remember the result
			pInstance->m_LastDirLightAmount = fDirLightAmount;
		}
		
		//setup the direction of the light
		LTVector vDirLightDir = g_pStruct->m_GlobalLightDir;
		if (bReallyClose)
		{
			// Put the lighting in our space
			g_ViewParams.m_mView.Apply3x3(vDirLightDir);
		}

		LTVector vScaledLightColor = g_pStruct->m_GlobalLightColor * fDirLightAmount;

		//add the directional light to the light list
		RenderLight.SetupDirLight(vDirLightDir, vScaledLightColor, FLAG_CASTSHADOWS);
		LightList.InsertLight(RenderLight, g_pStruct->m_GlobalLightConvertToAmbient);
	}

	// Ambient lighting
	if(g_have_world && g_CV_ModelApplyAmbient)
	{
		LTRGBColor ambientColor;
		w_DoLightLookup(world_bsp_shared->LightTable(), &vInstancePosition, &ambientColor);

		LTVector vAmbientLight;
		vAmbientLight.x = ambientColor.rgb.r;
		vAmbientLight.y = ambientColor.rgb.g;
		vAmbientLight.z = ambientColor.rgb.b;

		LightList.AddAmbient(vAmbientLight);
	}


	////////////////////////////////////////////////////////////////////
	// Figure out the lights that will be directionally lighting it.
	
	// Dynamic lights..
	for(uint32 i=0; i < g_nNumObjectDynamicLights; i++)
	{
		DynamicLight* pSrcLight = g_ObjectDynamicLights[i];

		if ((pSrcLight->m_Flags & FLAG_ONLYLIGHTWORLD) != 0)
			continue;

		LTVector vPos = pSrcLight->GetPos();
		if (bReallyClose)
		{
			// Put the lighting in our space
			vPos = g_ViewParams.m_mView * vPos;
		}

		LTVector vColor((float)pSrcLight->m_ColorR, (float)pSrcLight->m_ColorG, (float)pSrcLight->m_ColorB);
		LTVector vAttCoeff(1.0f, 0.0f, 19.0f/(pSrcLight->m_LightRadius*pSrcLight->m_LightRadius));
		RenderLight.SetupPointLight(vPos, vColor, vAttCoeff, pSrcLight->m_LightRadius, eAttenuation_D3D, 0);
		LightList.InsertLight(RenderLight, 0.0f);
	}

	// Static lights..
	if(g_have_world)
	{
		//fill out the callback data structure
		SStaticLightCallbackData CallbackData;
		CallbackData.m_pInstance	= pInstance;
		CallbackData.m_pLightList	= &LightList;

		//figure out what radius to use for this model
		float fModelRadius = pInstance->GetModelDB()->m_VisRadius;

		FindObjInfo foInfo;
		foInfo.m_iObjArray = NOA_Lights;
		foInfo.m_Min = vInstancePosition - LTVector(fModelRadius, fModelRadius, fModelRadius);
		foInfo.m_Max = vInstancePosition + LTVector(fModelRadius, fModelRadius, fModelRadius);
		foInfo.m_CB = &ModelDraw::StaticLightCB;
		foInfo.m_pCBUser = &CallbackData;

		world_bsp_client->ClientTree()->FindObjectsInBox2(&foInfo);
	}
}