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; }
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; }
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); } }