//===========================================================================// // File: SpringOf.hpp // Project: MechWarrior 4 // Contents: // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 03/20/00 JSE Initial coding, //---------------------------------------------------------------------------// // Copyright (C) 2000, Microsoft Corp. // All Rights reserved worldwide // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //===========================================================================// #pragma once #include "MW4.hpp" namespace MechWarrior4 { //########################################################################## //######################### SpringOf ############################### //########################################################################## template class SpringOf { public: T springLimit; T springConstant; T damageVelocity; T currentPosition; T currentVelocity; T forceLose; T notchVelocity; bool initialized; SpringOf() { initialized = false; } SpringOf(const T& spring_limit, const T& spring_constant, const T& force_lose, const T& notch_velocity) : springLimit(spring_limit) , springConstant(spring_constant) , forceLose(force_lose) , notchVelocity(notch_velocity) { initialized = true; for (int i = 0; i < T::GetMemberCount(); i++) { currentPosition[i] = 0.0f; currentVelocity[i] = 0.0f; damageVelocity[i] = 0.0f; } }; ~SpringOf(){}; void Initialize(const T& spring_limit, const T& spring_constant, const T& force_lose, const T& notch_velocity) { initialized = true; springLimit = spring_limit; springConstant = spring_constant; forceLose = force_lose; notchVelocity = notch_velocity; for (int i = 0; i < T::GetMemberCount(); i++) { currentPosition[i] = 0.0f; currentVelocity[i] = 0.0f; damageVelocity[i] = 0.0f; } }; void HitSpring(const T& how_hard) { Verify(initialized); for (int i = 0; i < T::GetMemberCount(); i++) { damageVelocity[i] += how_hard[i]; } } void Reset(void) { for (int i = 0; i < T::GetMemberCount(); i++) { currentPosition[i] = 0.0f; currentVelocity[i] = 0.0f; damageVelocity[i] = 0.0f; } } T GetCurrentPosition(void) { return currentPosition; }; void AdvanceTime(Stuff::Scalar time_slice) { Max_Clamp(time_slice, 0.2f); Verify(initialized); //--------------------------------------------- // calculate the distance we are stretched //--------------------------------------------- T return_velocity = T::Identity; T return_force = T::Identity; T delta_position = T::Identity; T last_position = currentPosition; for (int i = 0; i < T::GetMemberCount(); i++) { //--------------------------------------------- // calculate the return force //--------------------------------------------- return_force[i] = springConstant[i] * -currentPosition[i]; //--------------------------------------------- // cacluclate the return velocity //--------------------------------------------- return_velocity[i] = return_force[i] * time_slice; currentVelocity[i] += return_velocity[i]; //--------------------------------------------- // add the damage velocity //--------------------------------------------- currentVelocity[i] += damageVelocity[i]; // if velocity is appraoching zero... if (currentPosition[i] > 0.0f) { if (currentVelocity[i] < 0.0f) { Max_Clamp(currentVelocity[i], -notchVelocity[i]); } } else if (currentPosition[i] < 0.0f) { if (currentVelocity[i] > 0.0f) { Min_Clamp(currentVelocity[i], notchVelocity[i]); } } //--------------------------------------------- // Add the new positoin to the eye position. //--------------------------------------------- delta_position[i] = currentVelocity[i] * time_slice; currentPosition[i] += delta_position[i]; // if we are approaching zero if (Abs(currentVelocity[i]) <= notchVelocity[i]) { if (last_position[i] > 0.0f && currentPosition[i] <= 0.0f) { currentVelocity[i] = 0.0f; currentPosition[i] = 0.0f; } else if (last_position[i] < 0.0f && currentPosition[i] >= 0.0f) { currentVelocity[i] = 0.0f; currentPosition[i] = 0.0f; } } //--------------------------------------------- // Bleed some force off //--------------------------------------------- if (currentPosition[i] > 0.0f && currentVelocity[i] < 0.0f) { currentVelocity[i] += (forceLose[i] * time_slice); Max_Clamp(currentVelocity[i], 0.0f); } else if (currentPosition[i] < 0.0f && currentVelocity[i] > 0.0f) { currentVelocity[i] -= (forceLose[i] * time_slice); Min_Clamp(currentVelocity[i], 0.0f); } //----------------------------------------------------- // clamp the positions so it never goes out of bounds //----------------------------------------------------- if (currentPosition[i] > springLimit[i]) { currentVelocity[i] = 0.0f; currentPosition[i] = springLimit[i]; } else if (currentPosition[i] < -springLimit[i]) { currentVelocity[i] = 0.0f; currentPosition[i] = -springLimit[i]; } } damageVelocity = T::Identity; }; }; }