import java.lang.Math;
public class CameraPlayer extends CameraExtended
{
float _LEAN_ANGLE_RIGHT = -15;
float _LEAN_ANGLE_LEFT = 15;
float _LEAN_ANGLE_SPEED = 90f;
float _LEAN_DELTA_RIGHT = -40;
float _LEAN_DELTA_LEFT = 40;
float _LEAN_DELTA_SPEED = 220f;
float _LEAN_GUNPOS_COEF = 1.0f;//0.15f;
float m_fLeanAngle = 0;
float m_fDestLeanAngle = 0;
float m_fLeanDeltaZ = 0;
float m_fDestLeanDeltaZ = 0;
void StartLeaning(int nLeaning)
{
switch(nLeaning)
{
case Player._LEANING_RIGHT:
m_fDestLeanAngle = _LEAN_ANGLE_RIGHT;
m_fDestLeanDeltaZ = _LEAN_DELTA_RIGHT;
break;
case Player._LEANING_LEFT:
m_fDestLeanAngle = _LEAN_ANGLE_LEFT;
m_fDestLeanDeltaZ = _LEAN_DELTA_LEFT;
break;
}
}
void StopLeaning()
{
m_fDestLeanAngle = 0;
m_fDestLeanDeltaZ = 0;
}
void ForceStopLeaning()
{
m_fLeanAngle = m_fDestLeanAngle = 0;
m_fLeanDeltaZ = m_fDestLeanDeltaZ = 0;
}
boolean IsLeaning()
{
return ((m_fDestLeanAngle != 0 && m_fDestLeanDeltaZ != 0)||
(m_fLeanAngle != 0 || m_fLeanDeltaZ != 0));
}
// amplitudy do bujania w bobie
float _fAmplX = 2f;
float _fAmplY = 5f;
float _fAmplGunX = 2.2f;
float _fAmplGunY = 5.3f;
float _fAmplAimX = 0.8f;
float _fAmplAimY = 2f;
float _fAmplAimGunX = 0.9f;
float _fAmplAimGunY = 1.75f;
// czestotliwosc bujania w bobie
float _fPeriod = 0.5f;
// dla zwyklego chodzenia
float _fPeriodNormal = 0.5f;
// dla chodzenia po drabinie
float _fPeriodLadder = 0.13f;
// mnoznik amlitudy na drabinie w osi X
float _fClimbingAmplXCoeff = 0.f;//2.f;
// mnoznik amlitudy na drabinie w osi Y
float _fClimbingAmplYCoeff = 0.f;//0.9f;
// mnoznik czasu pojawiania sie amplitudy dla wchodzenia po drabinie
float _fClimbingAmplFadeInCoeff = 0.1f;
// czas w jakim amplituda boba sie wygasza lub pojawia
private float _fAmplFadeIn = 1.f;
private float _fAmplFadeOut = 0.1f;
// parametry okreslaja ksztalt krzywej do bujania podczas boba
private float _fOffset = 90f;
private float _fOffsetMul = 2f;
/** Tryby pracy kamery:
* (zmiany musza byc uwzglednione tablicy stanow aModes)
*/
final static byte CMODE_ZERO = -1;
final static byte CMODE_TPP = 0;
final static byte CMODE_FPP = 1;
final static byte CMODE_VEHICLE = 2;
final static byte CMODE_SNIPER = 3;
final static byte CMODE_BINOCULARS = 4;
final static byte CMODE_HEAVYGUN = 5;
final static byte CMODE_WALKER = 6;
final static byte CMODE_VEHICLE_PASSENGER = 7;
float m_fCurZoom = 1f; // SG
float m_fDestZoom = 1f; // not SG
/**Predkosc zoomowania*/
float m_fZoomSpeed = 10f; // not SG
/** Tablica stanow (= trybow pracy kamery)
*/
final static String[] aModes = {"ModeTPP", "ModeFPP", "ModeVehicle",
"ModeSniper", "ModeBinoculars", "ModeHeavyGun",
"ModeWalker", "ModeVehiclePassenger" };
/** Wartosc kata rozwarcia stozka widzenia gracza dla powiekszenia 1:1 (w stopniach)
*/
static float fFovAngle[] = {60.f, 82.f, 75.f, 75.f, 75.f, 75.f, 75.0f, 75.0f };
/** Tangens polowki kata stozka widzenia
*/
static float fFovTan[] = { (float)Math.tan(fFovAngle[0] * Math.PI / 360.f),
(float)Math.tan(fFovAngle[1] * Math.PI / 360.f),
(float)Math.tan(fFovAngle[2] * Math.PI / 360.f),
(float)Math.tan(fFovAngle[3] * Math.PI / 360.f),
(float)Math.tan(fFovAngle[4] * Math.PI / 360.f),
(float)Math.tan(fFovAngle[5] * Math.PI / 360.f),
(float)Math.tan(fFovAngle[5] * Math.PI / 360.f),
(float)Math.tan(fFovAngle[6] * Math.PI / 360.f)
};
/**
*/
float fNearClippingPlane = 8.0f;//35 // not SG
/**
*/
float fAimAngleY = 0.0f; // SG
/**Kat patrzenia dla trybu smochodowego.
*/
float fDeltaYVehicle = 0.0f; // SG
/** Maksymalna dlugosc strzalu z kamery do celownika. Nie moze byc za duze,
* bo bedzie zwalnialo strzelanie promienia.
*/
public static float fMaxTargetDist=25000.0f; // not SG
public static float fMaxTriggerDist=800.0f; // not SG
/** Jak bardzo [cm] ma byc srodek obrotu kamery wysuniety przed gracza
* (potrzebne do patrzenia pod nogi przy zbieraniu przedmiotow)
* Jest to wartosc maksymalna.
*/
public static float fForwardDistance = 50.f; // not SG
/** Minimum odsuniecia kamery od srodka obrotu - zeby nie ciac glowy Logana
* (nie bedzie potrzebne, jak sie zrobi blendowanie)
*/
public static float fMinBackDistance = 10.f; // not SG
/** Tablice parametrow dla roznych pozycji gracza - kolejno
* still, swim, crawl, duck, walk, run
*/
/** Tablica wysokosci kamery [cm]
*/
public static float fHeightDef[] = {200, 30, 30, 130, 200, 200, 200};
public static float fFPPHeightDef[] = {155, 30, 30, 100, 155, 155, 155};
// paramtry odpowiedzialne za aproksymacje przejsc
float fNewHeight = fHeightDef[0]; // SG
float fCurHeight = fNewHeight; // SG
float fOldHeight = fNewHeight; // SG
/** Tablica odsuniecia kamery do tylu od srodka obrotu [cm]
*/
public static float fBackDistanceDef[] = {500, 170, 170, 500, 500, 500, 500};
// paramtry odpowiedzialne za aproksymacje przejsc
float fNewBackDistance = fBackDistanceDef[0]; // SG
float fCurBackDistance = fNewBackDistance; // SG
float fOldBackDistance = fNewBackDistance; // SG
/** Parametry zwiazane z inercja kamery
*/
/** Czas potrzebny na pelna zmiane wysokosci [s]
*/
public static float fHeightChangeTime = 0.5f; //0.5f // not SG
/** Czas potrzebny na pelna zmiane odleglosci [s]
*/
public static float fDistChangeTime = 2.0f; //2.0f // not SG
/** Odleglosc w pionie oczu od kosci EBones._HEAD
* tryby: CS_FPP, CS_BINOCULARS
*/
public static float fHeadHeight = 15.f; // not SG
public static float fHeadDistance = 0.f; // not SG
/** Granica bezpieczenstwa dla traceowania promienia do przodu [cm]
*/
static float fDistEpsilon = 5.f; // not SG
/** Czas w ktorym nastapila zmiana ujecia [s]
*/
float fChangeTime = 0.0f; // not SG ???
/** Tryb pracy kamery */
byte nCurrentMode = CMODE_TPP; // SG
/** Poprzedni tryb pracy kamery */
byte nLastMode = CMODE_FPP; // SG
Vector vCameraPos=new Vector(); // SG
Vector vCameraMove= new Vector(); // SG
/** Player, ktorego pokazuje kamera
*/
Player Target=null; // SG
Vector vPushedPos = new Vector();
Vector vPushedFd = new Vector(0,0,1);
Vector vPushedUp = new Vector(0,1,0);
CameraPlayer thisCamera = this; // not SG
////////////////////////////////////////
// Trzesienie kamera (na sprezynach)
//
public static final int _SHAKE_EARTHQUAKE = 0;
public static final int _SHAKE_BUMP = 1;
public static final int _SHAKE_EXPLOSION = 2;
public static final int _SHAKE_TAKE_HIT = 3;
public static final int _SHAKE_STEPS = 4;
public static final int _SHAKE_VEHICLE = 5;
public static final int _SHAKE_CANNON = 6;
public static final int _SHAKE_CANNON_2 = 7;
public static final int _SHAKE_SPRINGS_NUM = 8;
/** Tablica sprezyn dla kamery */
CameraShakeSpring[] aCameraSpring = new CameraShakeSpring[_SHAKE_SPRINGS_NUM];
/** Predkosc (wymuszenie) sprezyny od trzesienia ziemi w pionie (max - brane z Randoma) */
public float fMaxEarthquakeSpringVelocityVert = 500;
/** Predkosc (wymuszenie) sprezyny od trzesienia ziemi w poziomie (max - brane z Randoma) */
public float fMaxEarthquakeSpringVelocityHoriz = 200;
float fLastSpringUpdate = 0; // not SG ???
/** ustawienia kamery gdy gracz kieruje pojazdem
*/
/** obnizenie pivota kamery */
static float _HEAVY_GUN_CAM_PIVOT_CORRECTION = 20f;
float m_fObservedSightVAngle = 15f; // SG
float m_fOverObservedHeight = 75f + _HEAVY_GUN_CAM_PIVOT_CORRECTION; // SG
float m_fOverObservedBack = 600f;
int METHOD_StopCameraBump = 0; // not SG
void OnCreate()
{
super.OnCreate();
Vector vPos = GetPosition();
vPos.fY = GetModule().GetWaterLevel() + 10.f;
FromForwardUpPos(new Vector(0,0,1), new Vector(0,1,0), vPos);
vPushedPos = vPos;
Log("CameraPlayer::OnCreate\n");
bSG = false;
InitializeSprings();
METHOD_StopCameraBump = RegisterCallMethod( "StopCameraBump" );
fChangeTime = GetTime();
}
float m_fDestOverObservedHeight = 0f;
float m_fDestOverObservedBack = 0f;
boolean m_bChangeOverObservedParams = false;
float m_fChangeOverObserverParamSpeed = 0.4f;
void ChangeOverObserverParams(float fDestHeight, float fDestBack)
{
m_fDestOverObservedHeight = fDestHeight;
m_fDestOverObservedBack = fDestBack;
m_bChangeOverObservedParams = true;
}
void UpdateOverObserverParams()
{
if (m_bChangeOverObservedParams)
{
m_fOverObservedHeight = m_fOverObservedHeight + (m_fDestOverObservedHeight - m_fOverObservedHeight) * m_fChangeOverObserverParamSpeed;
m_fOverObservedBack = m_fOverObservedBack + (m_fDestOverObservedBack - m_fOverObservedBack) * m_fChangeOverObserverParamSpeed;
if ( (m_fDestOverObservedHeight - m_fOverObservedHeight < 1f) &&
(m_fDestOverObservedBack - m_fOverObservedBack < 1f) )
{
m_fOverObservedHeight = m_fDestOverObservedHeight;
m_fOverObservedBack = m_fDestOverObservedBack;
m_bChangeOverObservedParams = false;
}
}
}
float GetStandardFOV()
{
return fFovAngle[2];
}
public void InitializeSprings()
{
CameraShakeSpring spring;
aCameraSpring[_SHAKE_EARTHQUAKE] = spring = new CameraShakeSpring(1, -0.4f);
spring.SetAttenuation(new Vector(0.93f, 0.93f, 0));
spring.SetForceFactor(new Vector(1900, 1900, 0));
aCameraSpring[_SHAKE_BUMP] = spring = new CameraShakeSpringBump(1, 0);
aCameraSpring[_SHAKE_EXPLOSION] = spring = new CameraShakeSpring(0, 1);
spring.SetAttenuation(new Vector(0.9f, 0.9f, 0.9f));
spring.SetForceFactor(new Vector(1800, 1800, 1800));
aCameraSpring[_SHAKE_TAKE_HIT] = spring = new CameraShakeSpring(0, 1);
spring.SetAttenuation(new Vector(0.85f, 0.85f, 0.85f));
spring.SetForceFactor(new Vector(1500, 1500, 1500));
aCameraSpring[_SHAKE_STEPS] = spring = new CameraShakeSpring(0, 1);
spring.SetAttenuation(new Vector(0.8f, 0.8f, 0.8f));
spring.SetForceFactor(new Vector(1800, 1800, 1800));
aCameraSpring[_SHAKE_VEHICLE] = spring = new CameraShakeSpring(0, 1);
spring.SetAttenuation(new Vector(0.85f, 0.85f, 0.85f));
spring.SetForceFactor(new Vector(1500, 1500, 1500));
aCameraSpring[_SHAKE_CANNON] = spring = new CameraShakeSpring(0.05f, 1);
spring.SetAttenuation(new Vector(0.5f, 0.5f, 0.5f));
spring.SetForceFactor(new Vector(4500, 4500, 4500));
aCameraSpring[_SHAKE_CANNON_2] = spring = new CameraShakeSpring(0.05f, 1);
spring.SetAttenuation(new Vector(0.65f, 0.65f, 0.65f));
spring.SetForceFactor(new Vector(5000, 5000, 5000));
}
void SetCannonSpringAtt(float fx)
{
aCameraSpring[_SHAKE_CANNON_2].SetAttenuation(new Vector(fx, fx, fx));
}
void SetCannonForceFactor(float f)
{
aCameraSpring[_SHAKE_CANNON_2].SetForceFactor(new Vector(f, f, f));
}
/** Wystartowanie trzesienia kamera przez okreslony czas */
public void StartEarthquakeShake(float fBetweenShakesTime, float fShakingTime)
{
CallMethodEvery("UpdateEarthquakeShake", fBetweenShakesTime);
CallMethodIn("StopEarthquakeShake", fShakingTime);
}
public void StopEarthquakeShake()
{
DisableCallMethod("UpdateEarthquakeShake");
DisableCallMethod("StopEarthquakeShake");
aCameraSpring[_SHAKE_EARTHQUAKE].SetPosition(Vector.Zero);
aCameraSpring[_SHAKE_EARTHQUAKE].SetVelocity(Vector.Zero);
}
/** Jednorazowe zatrzesienie kamera
*/
public void UpdateEarthquakeShake()
{
aCameraSpring[_SHAKE_EARTHQUAKE].SetVelocity(RandomFloat(-0.5f * fMaxEarthquakeSpringVelocityHoriz,
0.5f * fMaxEarthquakeSpringVelocityHoriz),
RandomFloat(-0.5f * fMaxEarthquakeSpringVelocityVert,
0.5f * fMaxEarthquakeSpringVelocityVert),
0);
fLastSpringUpdate = GetTime();
}
/**
* Tapniecie kamery, wolane gdy gracz zeskoczy na ziemie
*/
/** parametry: */
/** maksymalny czas trwania tapniecia */
public float m_fBumpMaxTime = 2.0f; // not SG
/** parametry minimalne (dla wspolczynnika 0.0) i maksymalne (dla 1.0)*/
/** Predkosc (wymuszenie) sprezyny w pionie przy tapnieciu */
public float m_fBumpSpringVelocityMin = - 500.0f; // not SG
public float m_fBumpSpringVelocityMax = -2000.0f; // not SG
/** Tlumienie w pionie przy tapnieciu*/
public float m_fBumpSpringAttenuationMin = 0.80f; // not SG
public float m_fBumpSpringAttenuationMax = 0.95f; // not SG
/** Sila sprezyny w pionie przy tapnieciu*/
public float m_fBumpSpringForceMin = 250.f; // not SG
public float m_fBumpSpringForceMax = 200.f; // not SG
/** Wystartowanie tapniecia kamera z odpowiednia sila*/
public void StartCameraBump(float fCoeff)
{
if ( fCoeff < 0.0f )
fCoeff = 0.0f;
else if ( fCoeff > 1.0f )
fCoeff = 1.0f;
float fVelocity = m_fBumpSpringVelocityMin+
fCoeff*(m_fBumpSpringVelocityMax-m_fBumpSpringVelocityMin);
float fAttenuation = m_fBumpSpringAttenuationMin+
fCoeff*(m_fBumpSpringAttenuationMax-m_fBumpSpringAttenuationMin);
float fForce = m_fBumpSpringForceMin+
fCoeff*(m_fBumpSpringForceMax-m_fBumpSpringForceMin);
StartCameraBump( fVelocity, fAttenuation, fForce );
}
public void StartCameraBump(float fSpringVelocity,
float fSpringAttenuation,
float fSpringForce )
{
aCameraSpring[_SHAKE_BUMP].SetVelocity( 0.0f, fSpringVelocity, 0.0f );
aCameraSpring[_SHAKE_BUMP].SetAttenuation( new Vector( 0.0f, fSpringAttenuation, 0.0f ));
aCameraSpring[_SHAKE_BUMP].SetForceFactor( new Vector( 0.0f, fSpringForce, 0.0f ) );
fLastSpringUpdate = GetTime();
DisableCallMethod( METHOD_StopCameraBump );
CallMethodIn( METHOD_StopCameraBump, m_fBumpMaxTime );
}
public void StopCameraBump()
{
aCameraSpring[_SHAKE_BUMP].SetPosition(Vector.Zero);
aCameraSpring[_SHAKE_BUMP].SetVelocity(Vector.Zero);
DisableCallMethod( METHOD_StopCameraBump );
}
public void UpdateCameraSprings()
{
float fTime = GetTime();
for (int i = 0; i < _SHAKE_SPRINGS_NUM; i++)
aCameraSpring[i].Update(fTime - fLastSpringUpdate);
fLastSpringUpdate = fTime;
}
private Vector m_vSCPNewPos = new Vector();
Vector ShakeCameraPos(Vector vPos)
{
m_vSCPNewPos.Set(vPos);
for (int i = 0; i < _SHAKE_SPRINGS_NUM; i++)
m_vSCPNewPos.Add(aCameraSpring[i].GetShakePos());
return m_vSCPNewPos;
}
/** maksymalny kat o jaki moze zmienic kierunek patrzenia kamery ShakeCameraDir
*/
public float m_fDirShakeConstraintAngle = 4.f;
private Vector m_vSCDOldFwd = new Vector();
private Vector m_vSCDNewFwd = new Vector();
private Vector m_vSCDCross = new Vector();
Vector ShakeCameraDir(Vector vFwd, float fAngleShakeMult)
{
m_vSCDOldFwd.Set(vFwd);
m_vSCDOldFwd.Normalize();
m_vSCDNewFwd.Set(m_vSCDOldFwd);
for (int i = 0; i < _SHAKE_SPRINGS_NUM; i++)
{
Vector vAngle = aCameraSpring[i].GetShakeAngle();
vAngle.Mul(fAngleShakeMult);
RotateVector(m_vSCDNewFwd, vAngle.fX, Vector.Up, m_vSCDNewFwd);
m_vSCDCross.Set(-m_vSCDNewFwd.fZ, 0, m_vSCDNewFwd.fX);
RotateVector(m_vSCDNewFwd, vAngle.fY, m_vSCDCross, m_vSCDNewFwd);
}
// dodaj zaleznosc sily trzesienia od kosinusa kierunku patrzenia i pionu (w pionie - zero)
float fUpDownCoef = 1.f - Math.abs(m_vSCDOldFwd.fY);
if (fUpDownCoef < 0)
fUpDownCoef = 0;
// zastosuj contrainta na obrot wektora
m_vSCDNewFwd.Normalize();
float fAngleDiff = Tools.RAD2DEG * Tools.acos(m_vSCDNewFwd.Dot(m_vSCDOldFwd));
float fMaxAngle = m_fDirShakeConstraintAngle * fUpDownCoef;
if (fAngleDiff > fMaxAngle)
{
m_vSCDOldFwd.CrossStatic(m_vSCDNewFwd, m_vSCDCross);
RotateVector(m_vSCDOldFwd, fMaxAngle, m_vSCDCross, m_vSCDNewFwd);
}
return m_vSCDNewFwd;
}
public void ShakeImpulse(Vector vImpulse, int nShakeType)
{
ShakeImpulse(vImpulse, nShakeType, true);
}
public void ShakeImpulse(Vector vImpulse, int nShakeType, boolean bAddImpulse)
{
if (bAddImpulse)
aCameraSpring[nShakeType].AddVelocity(vImpulse);
else
aCameraSpring[nShakeType].SetVelocity(vImpulse);
fLastSpringUpdate = GetTime();
UpdateCameraSprings();
}
public void ShakeImpulse(float fImpulseX, float fImpulseY, float fImpulseZ,
int nShakeType)
{
ShakeImpulse(fImpulseX, fImpulseY, fImpulseZ, nShakeType, true);
}
public void ShakeImpulse(float fImpulseX, float fImpulseY, float fImpulseZ,
int nShakeType, boolean bAddImpulse)
{
if (bAddImpulse)
aCameraSpring[nShakeType].AddVelocity(fImpulseX, fImpulseY, fImpulseZ);
else
aCameraSpring[nShakeType].SetVelocity(fImpulseX, fImpulseY, fImpulseZ);
fLastSpringUpdate = GetTime();
UpdateCameraSprings();
}
public void SetShakeAttenuationValue(float fValue, int nShakeType)
{
SetShakeAttenuation(fValue, fValue, fValue, nShakeType);
}
public void SetShakeAttenuation(float fX, float fY, float fZ, int nShakeType)
{
aCameraSpring[nShakeType].SetAttenuation(new Vector(fX, fY, fZ));
}
public void SetShakeForceFactorValue(float fValue, int nShakeType)
{
SetShakeForceFactor(fValue, fValue, fValue, nShakeType);
}
public void SetShakeForceFactor(float fX, float fY, float fZ, int nShakeType)
{
aCameraSpring[nShakeType].SetForceFactor(new Vector(fX, fY, fZ));
}
public void OnActivate()
{
super.OnActivate();
RegisterKeyRequest();
RegisterMouseAxisRequest();
RegisterMouseButtonRequest();
SetFOV(fFovAngle[CMODE_TPP]);
SetBaseFOV(fFovAngle[CMODE_TPP]);
SetClipNear(fNearClippingPlane);
// poczatkowe ustawienie widoku
FromForwardUpPos( vPushedFd, vPushedUp, vPushedPos);
SetState(aModes[nCurrentMode]);
}
public void OnDeactivate()
{
super.OnDeactivate();
vPushedPos = GetPosition();
vPushedFd = GetForwardVector();
vPushedUp = GetUpVector();
UnregisterKeyRequest();
UnregisterMouseAxisRequest();
}
/**************************************
* Poszczegolne tryby pracy kamery
*/
/** Tryb trzeciej osoby - kamera znajduje sie w.....
* TODO: opis zachowania
*/
public class ModeTPP extends State
{
public void OnEnter()
{
nCurrentMode = CMODE_TPP;
SetFOV(fFovAngle[CMODE_TPP]);
SetBaseFOV(fFovAngle[CMODE_TPP]);
SetClipNear(fNearClippingPlane);
}
public void OnPostUpdate()
{
UpdateCameraSprings();
UpdateCameraZoom();
if ( Target != null )
{
//vCameraPos.Set(Target.GetPosition());
Target.GetRenderPosition( vCameraPos );
float fTau = InterpolateMove(fChangeTime, fHeightChangeTime);
fCurHeight = fNewHeight * fTau + fOldHeight * (1.f - fTau);
// przesuwamy kamere do gory na wysokosc
vCameraPos.fY+=fCurHeight;
// przesuwamy kamere przed gracza, zeby patrzyla mu pod nogi
Vector vFwd = Target.GetCameraForwardVector();
float fFwdDst = CheckMaxDistance(vCameraPos, vFwd, fForwardDistance);
vFwd.Mul(Math.max(fFwdDst - fDistEpsilon, 0.f));
vCameraPos.Add(vFwd);
// dokladamy do ruchu kamery ruch myszy
float fY = - (float)java.lang.Math.sin( fAimAngleY );
float fZ = (float)java.lang.Math.cos( fAimAngleY );
vCameraMove.Set(Target.GetCameraForwardVector());
vCameraMove.Mul(fZ);
vCameraMove.fY = fY;
vCameraMove.Normalize();
vCameraMove.Mul(-1);
fTau = InterpolateMove(fChangeTime, fDistChangeTime);
fCurBackDistance = fNewBackDistance * fTau + fOldBackDistance * (1.f - fTau);
// odsuwamy kamere w tyl o max. fCurBackDistance
vCameraMove.Mul(Math.max(CheckMaxDistance(vCameraPos, vCameraMove, fCurBackDistance),
fMinBackDistance));
vCameraPos.Add(vCameraMove);
//
FromForwardUpPos( ShakeCameraDir(vCameraMove, 1), Vector.Up, vCameraPos );
}
UpdatePlayerSpeaker();
}
}
// tymczasowa zmienna do operowania na wektorkach
static Vector l_vFdMFOPU = new Vector(); // not SG
// wlacza bobowanie guna
boolean bBobWithGun = false;
boolean bTargetLock = true;
float fTargetLockDist = 10000f;
/** O ile ma byc podniesiona kamera w stosunku do swojej minimalnej pozycji
*/
float m_fMinCameraHeightAdd = 45;
/** Tryb pierwszej osoby - wylaczenie renderingu gracza
* i umieszczenie kamery gdzies w jego glowie
*/
public class ModeFPP extends State
{
Lissajouxer cLisCamera = null;
Lissajouxer cLisGun = null;
public void OnEnter()
{
nCurrentMode = CMODE_FPP;
SetFOV(fFovAngle[CMODE_FPP]);
SetBaseFOV(fFovAngle[CMODE_TPP]);
SetClipNear(fNearClippingPlane);
MakeLis();
fAmplX = _fAmplX;
fAmplY = _fAmplY;
fAmplGunX = _fAmplGunX;
fAmplGunY = _fAmplGunY;
PrepareCameraEllipsoid();
}
void MakeLis()
{
// tworzymy obiekty do ruszania gunem i camera
if(cLisCamera == null) cLisCamera = new Lissajouxer(CameraPlayer.this, _fAmplX, _fAmplY, _fOffset, _fOffsetMul, _fPeriod, _fAmplFadeIn);
if(cLisGun == null) cLisGun = new Lissajouxer(CameraPlayer.this, _fAmplGunX, _fAmplGunY, _fOffset, _fOffsetMul, _fPeriod, _fAmplFadeIn);
}
float fLisMove = 0;
Vector vTargetPrevPos = new Vector();
MotionState cTargetMotionPrev = new MotionState();
float fTargetSpeedPrev = 0.f;
boolean bTragetJumplingPrev = false;
float fAmplX = 0.0f;
float fAmplY = 0.0f;
float fAmplGunX = 0.0f;
float fAmplGunY = 0.0f;
// wektor do zapamietywania pozycji
Vector vSpeed = new Vector();
// bujanie kamera
void Bob()
{
// wyliczamy predkosc gracza
Target.GetLocalRenderingPosition(vSpeed);
if (Target.motion.nClimbing == MotionState._CLIMBING_FALSE)
vSpeed.fY = 0;
vSpeed.Sub(vTargetPrevPos);
Target.GetLocalRenderingPosition(vTargetPrevPos);
if (Target.motion.nClimbing == MotionState._CLIMBING_FALSE)
vTargetPrevPos.fY = 0;
float fTargetSpeed = vSpeed.Len();
// ograniczenie na przesuniecie, zeby nie bylo skokow
if(fTargetSpeed < 100.f)
// ustalamy wartosc przesuniecia z przeliczeniem na km
fLisMove += fTargetSpeed/1000.f;
else
fTargetSpeed = 0.0f;
boolean bForceAmplRefresh = false;
// wyciagamy parametry z broni
Weapon cWeapon = Target.ActiveWeapon;
if(cWeapon != null)
{
/*
_fAmplX = cWeapon.fBobAmplitudeX;
_fAmplY = cWeapon.fBobAmplitudeY;
_fAmplGunX = cWeapon.fBobAmplitudeGunX;
_fAmplGunY = cWeapon.fBobAmplitudeGunY;
_fAmplAimX = cWeapon.fBobAmplitudeAimX;
_fAmplAimY = cWeapon.fBobAmplitudeAimY;
_fAmplAimGunX = cWeapon.fBobAmplitudeAimGunX;
_fAmplAimGunY = cWeapon.fBobAmplitudeAimGunY;
cLisCamera.SetPeriod(cWeapon.fBobPeriod);
cLisGun.SetPeriod(cWeapon.fBobPeriod);
*/
}
//--------- sprawdzamy czy gracz przycelowuje
// zmienamy parametry, gdy gracz wlacza przycelowanie
if(!cTargetMotionPrev.bAiming && Target.motion.bAiming)
{
fAmplX = _fAmplAimX;
fAmplY = _fAmplAimY;
fAmplGunX = _fAmplAimGunX;
fAmplGunY = _fAmplAimGunY;
bForceAmplRefresh = true;
}
// zmieniamy parametry gdy gracz wylacza przycelowanie
if(cTargetMotionPrev.bAiming && !Target.motion.bAiming)
{
fAmplX = _fAmplX;
fAmplY = _fAmplY;
fAmplGunX = _fAmplGunX;
fAmplGunY = _fAmplGunY;
bForceAmplRefresh = true;
}
if(cTargetMotionPrev.nClimbing != Target.motion.nClimbing)
bForceAmplRefresh = true;
// zapamietujemy poprzedni stan gracza
cTargetMotionPrev.Set(Target.motion);
//--------- sprawdzamy czy gracz skacze
if( !bTragetJumplingPrev && Target.AmIFlying())
{
cLisCamera.SetAmpl(0f,0f, _fAmplFadeOut);
cLisGun.SetAmpl(0f,0f, _fAmplFadeOut);
bForceAmplRefresh = false;
}
if( bTragetJumplingPrev && !Target.AmIFlying())
{
bForceAmplRefresh = true;
}
bTragetJumplingPrev = Target.AmIFlying();
//--------- sprawdzamy czy gracz porusza sie
// gracz zatrzymuje sie
if(fTargetSpeedPrev != 0.0f && fTargetSpeed == 0.0f)
{
cLisCamera.SetAmpl(0f,0f, _fAmplFadeOut);
cLisGun.SetAmpl(0f,0f, _fAmplFadeOut);
bForceAmplRefresh = false;
}
// gracz zaczyna isc
if(fTargetSpeedPrev == 0.0f && fTargetSpeed != 0.0f)
bForceAmplRefresh = true;
// ustawiamy amplitude
if(bForceAmplRefresh && fTargetSpeed != 0.0f)
{
if (Target.motion.nClimbing > MotionState._CLIMBING_FALSE)
{
cLisCamera.SetPeriod(_fPeriodLadder);
cLisCamera.SetAmpl(fAmplX * _fClimbingAmplXCoeff, fAmplY * _fClimbingAmplYCoeff, _fAmplFadeIn * _fClimbingAmplFadeInCoeff);
cLisGun.SetPeriod(_fPeriodLadder);
cLisGun.SetAmpl(fAmplGunX * _fClimbingAmplXCoeff, fAmplGunY * _fClimbingAmplYCoeff, _fAmplFadeIn * _fClimbingAmplFadeInCoeff);
}
else
{
cLisCamera.SetPeriod(_fPeriodNormal);
cLisCamera.SetAmpl(fAmplX, fAmplY, _fAmplFadeIn);
cLisGun.SetPeriod(_fPeriodNormal);
cLisGun.SetAmpl(fAmplGunX, fAmplGunY, _fAmplFadeIn);
}
}
// zapamietujemy poprzednia predkosc
fTargetSpeedPrev = fTargetSpeed;
//--------- updejtujemy krzywe
cLisCamera.Update(fLisMove);
cLisGun.Update(fLisMove);
}
Vector l_vCamUp = new Vector(Vector.Up);
Vector l_vCamForward = new Vector();
Vector l_vPrevCamPos = new Vector();
float fLastFrameTime = 0;
public void OnPostUpdate()
{
if (fLastFrameTime == 0)
fLastFrameTime = GetTime();
Vector.count = true;
if ( Target != null )
{
if (!Target.bDead)
{
UpdateCameraSprings();
UpdateCameraZoom();
l_vPrevCamPos.Set(vCameraPos);
if (m_fDestLeanDeltaZ != m_fLeanDeltaZ)
{
if (m_fLeanDeltaZ < m_fDestLeanDeltaZ)
{
m_fLeanDeltaZ += (GetTime() - fLastFrameTime) * _LEAN_DELTA_SPEED;
if (m_fLeanDeltaZ > m_fDestLeanDeltaZ)
m_fLeanDeltaZ = m_fDestLeanDeltaZ;
}
else
if (m_fLeanDeltaZ > m_fDestLeanDeltaZ)
{
m_fLeanDeltaZ -= (GetTime() - fLastFrameTime) * _LEAN_DELTA_SPEED;
if (m_fLeanDeltaZ < m_fDestLeanDeltaZ)
m_fLeanDeltaZ = m_fDestLeanDeltaZ;
}
}
Target.GetRenderPositionWithLeaning(vCameraPos, m_fLeanDeltaZ);
}
else
{
Target.GetEyePos(vCameraPos);
}
float fMinYPos = vCameraPos.fY + m_fMinCameraHeightAdd;
float fTau = InterpolateMove(fChangeTime, fHeightChangeTime);
fCurHeight = fNewHeight * fTau + fOldHeight * (1.f - fTau);
if (!Target.bDead)
{
// przesuwamy kamere do gory na wysokosc
vCameraPos.fY += fCurHeight;
if (IsLeaning())
vCameraPos = ClipCameraForLeaning(l_vPrevCamPos, vCameraPos);
Bob();
}
float fNewAngle = fAimAngleY;
if (fAimAngleY >= 0)
{
fNewAngle = (float)(fCurHeight * Math.tan(fAimAngleY) / (fCurHeight));
fNewAngle = (float)Math.atan(fNewAngle);
}
// dokladamy do ruchu kamery ruch myszy
float fY = - (float)java.lang.Math.sin( fNewAngle);//fAimAngleY );
float fZ = (float)java.lang.Math.cos( fNewAngle);//fAimAngleY );
if (!Target.bDead)
{
Target.GetCameraForwardVector(vCameraMove);
vCameraMove.Mul(fZ);
vCameraMove.fY = fY;
}
else
{
Target.GetEyeForwardVector(vCameraMove);
}
vCameraMove.Normalize();
vCameraMove.Negate();
vCameraPos = ShakeCameraPos(vCameraPos);
Vector vDir = ShakeCameraDir(vCameraMove, 1);
// robimy pozycje kamery z bobem
Vector vBobRight = Vector.Cross(vDir, Vector.Up);
vBobRight.Normalize();
vBobRight.Mul(cLisCamera.GetSinX());
Vector vBobCamerPos = new Vector(vCameraPos);
vBobCamerPos.fY += cLisCamera.GetSinY();
vBobCamerPos.Add(vBobRight);
// ustawiamy kamere celownikiem na srodek ekranu
if(bTargetLock)
{
Vector vTarget = new Vector(vDir);
vTarget.Mul(-fTargetLockDist);
vTarget.Add(vCameraPos);
vDir.Set(vBobCamerPos);
vDir.Sub(vTarget);
vDir.Normalize();
}
// vBobCamerPos.Add(cCameraImpulseSpring.GetPosition());
l_vCamUp.Set(Vector.Up);
//l_vCamUp = Target.VectorLocalToWorld(l_vCamUp);
//l_vCamUp.Add(GetRightVectorVolatile());
//l_vCamUp.Normalize();
if (m_fDestLeanAngle != m_fLeanAngle)
{
if (m_fLeanAngle < m_fDestLeanAngle)
{
m_fLeanAngle += (GetTime() - fLastFrameTime) * _LEAN_ANGLE_SPEED;
if (m_fLeanAngle > m_fDestLeanAngle)
m_fLeanAngle = m_fDestLeanAngle;
}
else
if (m_fLeanAngle > m_fDestLeanAngle)
{
m_fLeanAngle -= (GetTime() - fLastFrameTime) * _LEAN_ANGLE_SPEED;
if (m_fLeanAngle < m_fDestLeanAngle)
m_fLeanAngle = m_fDestLeanAngle;
}
l_vCamForward.Set(GetForwardVector());
}
if (m_fLeanAngle != 0)
Target.RotateVector(l_vCamUp, m_fLeanAngle, l_vCamForward, l_vCamUp);//l_vCamUp.fZ = -0.60f;
if (vBobCamerPos.fY < fMinYPos)
vBobCamerPos.fY = fMinYPos;
FromForwardUpPos(vDir, l_vCamUp, vBobCamerPos );
Target.GetCameraForwardVector(l_vFdMFOPU);
//ustaw rece FPP w stosunku do kamery
Vector vPos = null;
if(bBobWithGun)
{
vPos = vBobCamerPos;
}
else
{
Vector vBobGunRight = Vector.Cross(vDir, Vector.Up);
vBobGunRight.Normalize();
vBobGunRight.Mul(cLisGun.GetSinX());
Vector vBobGunPos = new Vector(vCameraPos);
vBobGunPos.fY += cLisGun.GetSinY();
vBobGunPos.Add(vBobGunRight);
vPos = vBobGunPos;
}
if (m_fLeanDeltaZ != 0)
{
//vPos.fY -= (float)Math.abs(m_fLeanDeltaZ) * _LEAN_GUNPOS_COEF;
float fPosAdd = (float)Math.abs(m_fLeanDeltaZ) * _LEAN_GUNPOS_COEF;
Vector vPosAdd = GetUpVector();
vPosAdd.Mul(-fPosAdd);
vPos.Add(vPosAdd);
l_vCamUp.fX *= -1;
l_vCamUp.fZ *= -1;
}
Target.SetHandsPos(l_vFdMFOPU, l_vCamUp, vPos, thisCamera, fNewAngle);
}
Vector.count = false;
UpdatePlayerSpeaker();
fLastFrameTime = GetTime();
}
//*********************************************************
// SaveGame
//*********************************************************
public void SGLoad(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer$ModeFPP] : SGLoad\n");
FileChunk cFC = GameObject.LoadChunk(cParentFC);
if (cFC.GetID() == ESGChunksChrome._CHK_CAMERA_PLAYER_MODE_FPP_STATE)
{
super.SGLoad(cFC);
//cLisCamera.SGLoadChunk(cFC);
//cLisGun.SGLoadChunk(cFC);
fLisMove = cFC.LoadFloat();
vTargetPrevPos = cFC.LoadVector();
fTargetSpeedPrev = cFC.LoadFloat();
bTragetJumplingPrev = cFC.LoadBool();
cTargetMotionPrev = (MotionState)cFC.LoadObject(cTargetMotionPrev,null);
fAmplX = cFC.LoadFloat();
fAmplY = cFC.LoadFloat();
fAmplGunX = cFC.LoadFloat();
fAmplGunY = cFC.LoadFloat();
}
cFC.delete();
}
public void SGSave(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer$ModeFPP] : SGSave\n");
FileChunk cFC = NewChunk(ESGChunksChrome._CHK_CAMERA_PLAYER_MODE_FPP_STATE, cParentFC);
super.SGSave(cFC);
//cLisCamera.SGSaveChunk(cFC);
//cLisGun.SGSaveChunk(cFC);
cFC.SaveFloat(fLisMove);
cFC.SaveVector(vTargetPrevPos);
cFC.SaveFloat(fTargetSpeedPrev);
cFC.SaveBool(bTragetJumplingPrev);
cFC.SaveObject(cTargetMotionPrev);
cFC.SaveFloat(fAmplX);
cFC.SaveFloat(fAmplY);
cFC.SaveFloat(fAmplGunX);
cFC.SaveFloat(fAmplGunY);
cFC.delete();
}
public void SGUpdate()
{
FileChunk.Log("[CameraPlayer$ModeFPP] : SGUpdate\n");
nCurrentMode = CMODE_FPP;
SetFOV(fFovAngle[CMODE_FPP]);
SetBaseFOV(fFovAngle[CMODE_TPP]);
SetClipNear(fNearClippingPlane);
fLastFrameTime = GetTime();
MakeLis();
}
}
/** Tryb snajpera - wylaczenie renderingu gracza
* i umieszczenie kamery gdzies w broni
*/
public class ModeSniper extends State
{
public void OnEnter()
{
nCurrentMode = CMODE_SNIPER;
}
Vector l_vHandsDir = new Vector();
public void OnPostUpdate()
{
UpdateCameraSprings();
UpdateCameraZoom();
if ( Target != null )
{
//vCameraPos.Set(Target.GetPosition());
Target.GetRenderPosition( vCameraPos );
float fTau = InterpolateMove(fChangeTime, fHeightChangeTime);
fCurHeight = fNewHeight * fTau + fOldHeight * (1.f - fTau);
vCameraPos.fY += fCurHeight;
// dokladamy do ruchu kamery ruch myszy
float fY = - (float)java.lang.Math.sin( fAimAngleY );
float fZ = (float)java.lang.Math.cos( fAimAngleY );
Target.GetCameraForwardVector(vCameraMove);
vCameraMove.Mul(fZ);
vCameraMove.fY = fY;
vCameraMove.Normalize();
vCameraMove.Mul(-1);
vCameraPos = ShakeCameraPos(vCameraPos);
FromForwardUpPos( ShakeCameraDir(vCameraMove, 1), Vector.Up, vCameraPos );
Target.GetCameraForwardVector(l_vHandsDir);
//ustaw rece FPP w stosunku do kamery
Target.SetHandsPos(l_vHandsDir, Vector.Up, vCameraPos, thisCamera, fAimAngleY);
}
UpdatePlayerSpeaker();
}
}
/** Tryb lornetki - wylaczenie renderingu gracza
* i umieszczenie kamery gdzies w jego glowie
* z umozliwieniem zoomowania
*/
public class ModeBinoculars extends ModeFPP
{
public void OnEnter()
{
nCurrentMode = CMODE_BINOCULARS;
}
}
/** sprezyna symulujaca "uginanie" sie kamery w pojezdzie na wybojach */
Spring cCameraYSpring = new Spring();
float fLastVehicleYPos = 0f;
float fLastVehicleYSpeed = 0f;
float fLastVehicleYSpeedDiff = 0f;
float fLastCamPosYUpdateTime = 0f;
float fAmplitudeCoeff = 0.3f;
Vehicle vehicleToUpdateSpring = null;
boolean m_bFirstUpdate = false;
public void PrepareYSpring()
{
cCameraYSpring.SetPosition(Vector.Zero);
fLastCamPosYUpdateTime = GetTime();
if (Target != null && Target.GetSeat() != null && Target.GetSeat().GetOccupiedObject() instanceof Vehicle)
{
vehicleToUpdateSpring = (Vehicle) Target.GetSeat().GetOccupiedObject();
cCameraYSpring.SetAttenuation(new Vector(vehicleToUpdateSpring.GetCameraAttenuation(), 0f, 0f));
cCameraYSpring.SetForceFactor(new Vector(vehicleToUpdateSpring.GetCameraForceFactor(), 0f, 0f));
this.fAmplitudeCoeff = vehicleToUpdateSpring.GetAmplitudeCoeff();
fLastVehicleYSpeed = 0f;
fLastVehicleYPos = vehicleToUpdateSpring.GetPosition().fY;
m_bFirstUpdate = true;
}
else
vehicleToUpdateSpring = null;
}
public float UpdateCameraY(Vector vPos)
{
if (vehicleToUpdateSpring == null)
return 0f;
float fTime = GetTime();
if (fTime - fLastCamPosYUpdateTime <= 0f)
return 0f;
if (m_bFirstUpdate)
{
fLastVehicleYPos = vPos.fY;
m_bFirstUpdate = false;
}
cCameraYSpring.Calculate(fTime - fLastCamPosYUpdateTime);
Vector vRenderPos = new Vector(vPos);
//vehicleToUpdateSpring.GetRenderPosition( vRenderPos, null, null );
float fCurrYSpeed = (vRenderPos.fY - fLastVehicleYPos) / (fTime - fLastCamPosYUpdateTime);
float fSpeedYDiff = fCurrYSpeed - fLastVehicleYSpeed;
cCameraYSpring.AddVelocity(-fSpeedYDiff * fAmplitudeCoeff, 0f, 0f);
fLastVehicleYSpeed = fCurrYSpeed;
fLastVehicleYPos = vRenderPos.fY;
fLastVehicleYSpeedDiff = fSpeedYDiff;
fLastCamPosYUpdateTime = fTime;
return cCameraYSpring.GetPosition().fX;
}
/** Kamera za samochodem:
* o zachowuje bezwladnosc
* o nie umozliwia rozgladania
*/
public class ModeVehicle extends State
{
Vector vCameraPosOld;
Vector vCameraMoveOld;
float m_fDirDelay = 15f;
Vector vCarRenderPos;
Vector vCarRenderDir;
Vector vCarRenderRight;
public void OnEnter()
{
//LogR("CameraPlayer.ModeVehicle.OnEnter\n");
nCurrentMode = CMODE_VEHICLE;
if (Target == null)
{
CrashLog("CameraPlayer.ModeVehicle error: Target == null\n");
return;
}
vCarRenderPos = new Vector();
vCarRenderDir = new Vector();
vCarRenderRight = new Vector();
Target.GetCarRenderPosition( vCarRenderPos, vCarRenderDir, vCarRenderRight );
Vector vTemp = new Vector(vCarRenderDir);
vTemp.Negate();
FromForwardUpPos(vTemp, Target.GetUpVector(), GetPosition());
vCameraPosOld = new Vector(vCameraPos);
vCameraMoveOld = new Vector(vCameraMove);
PrepareYSpring();
PrepareCameraEllipsoid();
}
void SetCamPosDir(Vector vPos, Vector vDir)
{
Vector vBase = new Vector();
Vector m_vCamBaseY = new Vector();
Vector m_vCamBaseZ = new Vector();
m_vCamBaseZ.Set(0, 0, 1f);
m_vCamBaseY.Set(0, 1f, 0);
vDir.Negate();
vBase.Set(vDir);
vBase.fX = 0f;
vBase.Normalize();
vBase.Set(vDir);
vBase.fY = 0;
vBase.Normalize();
m_vCamBaseZ.Set(vDir);
m_vCamBaseZ.Normalize();
float fDot = Vector.Up.Dot(m_vCamBaseZ);
if (fDot == 1f)
vBase.Set(m_vCamBaseZ.Cross(Vector.Forward));
else
if (fDot == -1f)
vBase.Set(Vector.Forward.Cross(m_vCamBaseZ));
else
vBase.Set(Vector.Up.Cross(m_vCamBaseZ));
vBase.Normalize();
m_vCamBaseY.Set(m_vCamBaseZ.Cross(vBase));
Vector vTemp = new Vector(vPos);
vPos.fY += m_fOverObservedHeight;
vDir.Mul(m_fOverObservedBack);
vPos.Add(vDir);
m_vCamBaseZ = ShakeCameraDir(m_vCamBaseZ, 0.2f);
vPos = ShakeCameraPos(vPos);
if (Target.GetSeat() != null)
{
ControlObject occupied = (ControlObject) Target.GetSeat().GetOccupiedObject();
vPos = ClipCamera(vTemp, vPos, occupied);
}
float fSpringCorrection = UpdateCameraY(vPos);
if (fSpringCorrection > m_fOverObservedHeight * 0.5f)
fSpringCorrection = m_fOverObservedHeight * 0.5f;
vPos.fY += fSpringCorrection;
FromForwardUpPos(m_vCamBaseZ, m_vCamBaseY, vPos);
}
public void OnPostUpdate()
{
UpdateCameraSprings();
UpdateCameraZoom();
if ( (Target != null) && (Target.cSeatInfo != null) )
{
Target.GetCarRenderPosition( vCarRenderPos,
vCarRenderDir,
vCarRenderRight );
Vector vDestCamDir = vCarRenderDir;
// ustawienie sie na pojezdzie
Vector vCurrCamDir = GetForwardVector();
vCurrCamDir.Negate();
vDestCamDir = RotateVector( vDestCamDir,
m_fObservedSightVAngle,
vCarRenderRight );
vCurrCamDir.fX = vCurrCamDir.fX + (vDestCamDir.fX - vCurrCamDir.fX) / m_fDirDelay;
vCurrCamDir.fY = vCurrCamDir.fY + (vDestCamDir.fY - vCurrCamDir.fY) / m_fDirDelay;
vCurrCamDir.fZ = vCurrCamDir.fZ + (vDestCamDir.fZ - vCurrCamDir.fZ) / m_fDirDelay;
SetCamPosDir( vCarRenderPos, vCurrCamDir );
}
UpdatePlayerSpeaker();
UpdateOverObserverParams();
}
//*********************************************************
// SaveGame
//*********************************************************
public void SGLoad(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer$ModeVehicle] : SGLoad\n");
FileChunk cFC = GameObject.LoadChunk(cParentFC);
if (cFC.GetID() == ESGChunksChrome._CHK_CAMERA_PLAYER_MODE_VEHICLE_STATE)
{
super.SGLoad(cFC);
vCameraPosOld = cFC.LoadVector();
vCameraMoveOld = cFC.LoadVector();
m_fDirDelay = cFC.LoadFloat();
}
cFC.delete();
}
public void SGSave(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer$ModeVehicle] : SGSave\n");
FileChunk cFC = NewChunk(ESGChunksChrome._CHK_CAMERA_PLAYER_MODE_VEHICLE_STATE, cParentFC);
super.SGSave(cFC);
cFC.SaveVector(vCameraPosOld);
cFC.SaveVector(vCameraMoveOld);
cFC.SaveFloat(m_fDirDelay);
cFC.delete();
}
public void SGUpdate()
{
FileChunk.Log("[CameraPlayer$ModeVehicle] : SGUpdate\n");
nCurrentMode = CMODE_VEHICLE;
}
}
/** bron, znad ktorej patrzymy */
ICannonController m_HeavyWeapon = null; // SG
MeshObject m_WeaponOwner = null; // SG
Vector m_vGunLookDir = null; // not SG
float m_fOverGunHeight = 75f; // SG
float m_fOverGunBack = 600f; // SG
float m_fOverGunHeightAim = 40; // SG
float m_fOverGunBackAim = 80; // SG
float m_fOverGunFOV = 82f; // SG
float m_fOverGunAimFOV = 60f; // SG
float m_fOldFOV = 82f; // SG
Vector m_vOldUp = new Vector(); // SG
Vector m_vOldForward = new Vector(); // SG
float m_fGunMouseSensitivityMul = 30f; // not SG
float m_fOldOverObservedHeight; // SG
float m_fOldOverObservedBack; // SG
/** metoda wolana, gdy wektor kamery zmienia sie na skutek zmiany orientacji
* obiektu, z nad ktorego patrzy kamera (np. pojazd)
*/
void SetWeaponToViewOver(ICannonController heavyWeapon, MeshObject weaponOwner, boolean bUseGyro)
{
m_HeavyWeapon = heavyWeapon;
m_WeaponOwner = weaponOwner;
m_vGunLookDir = null;
m_bUseGyro = bUseGyro;
m_vStartGunDir.Set(weaponOwner.GetForwardVectorVolatile());
}
/** Wersja bez aiming
*/
void SetCameraOverGunPosition(float fOverGunHeight, float fOverGunBack,
float fOverGunFOV, float fOverGunAimFOV)
{
m_fOverGunHeight = fOverGunHeight;
m_fOverGunBack = fOverGunBack;
m_fOverGunFOV = fOverGunFOV;
m_fOverGunAimFOV = fOverGunAimFOV;
m_fOldFOV = GetFOV();
m_bAimingAllowed = false;
}
/** Wersja z aiming
*/
void SetCameraOverGunPosition(float fOverGunHeight, float fOverGunBack,
float fOverGunHeightAim, float fOverGunBackAim,
float fOverGunFOV, float fOverGunAimFOV)
{
m_fOverGunHeight = fOverGunHeight;
m_fOverGunBack = fOverGunBack;
m_fOverGunHeightAim = fOverGunHeightAim;
m_fOverGunBackAim = fOverGunBackAim;
m_fOldFOV = GetFOV();
m_bAimingAllowed = true;
}
void RestoreCameraDefaults()
{
m_fOverObservedHeight = m_fOldOverObservedHeight;
m_fOverObservedBack = m_fOldOverObservedBack;
SetFOV(m_fOldFOV);
}
void StoreCameraDefaults()
{
m_fOldOverObservedHeight = m_fOverObservedHeight;
m_fOldOverObservedBack = m_fOverObservedBack;
m_fOldFOV = GetFOV();
}
/** dummy, ktorego ellipsoide uzywamy */
MeshObject cMesh = null;
/** szybkosc wycofywania sie kamery */
float fCameraBackSpeed = 3000f;
float fLastClipDist = 0f;
float fLastClipUpdateTime = 0f;
float fDummyRadius = 15f;
void SetDummyEllipsoid()
{
if (cMesh != null)
cMesh.SetEllipsoid(fDummyRadius, fDummyRadius, 0f);
}
void PrepareCameraEllipsoid()
{
fLastClipDist = 1000000f;
fLastClipUpdateTime = GetTime();
if (cMesh != null)
return;
cMesh = (MeshObject) CreateObject("MeshObject");
cMesh.LoadMesh("Data/Interface/zarowka.3da");
cMesh.ActivateOnModule();
cMesh.ClearFlag(EFlags._BLOCK_MOVE);
cMesh.ClearFlag(EFlags._BLOCK_TRACE);
cMesh.SetCollAction(ECollFlags.OBJCOL_ACTION_STOP);
cMesh.SetCollHandler(ECollFlags.OBJCOL_HANDLER_NONE);
cMesh.SetLighting(false);
cMesh.EnableRendering(false);
SetDummyEllipsoid();
}
Vector ClipCameraForLeaning(Vector vStart, Vector vEnd)
{
int iOwnerFlags = 0;
if (Target != null)
{
iOwnerFlags = Target.GetFlags();
Target.ClearFlag(EFlags._COLLISION);
}
cMesh.SetPositionWorld(vStart);
vEnd.Sub(vStart);
cMesh.MoveByEllipsoidPure(vEnd);
vEnd.Add(vStart);
//fLastClipUpdateTime = fCurrTime;
// przywracamy kolizje
if (Target != null)
{
Target.SetFlags(iOwnerFlags);
}
return vEnd;
}
Vector ClipCamera(Vector vStart, Vector vEnd, ControlObject obj)
{
// wylaczamy kolizje obiektowi i jego pasazerom
int iOwnerFlags = 0;
if (obj != null)
{
iOwnerFlags = obj.GetFlags();
obj.ClearFlag(EFlags._COLLISION);
if (obj instanceof ISeatVehicle)
((ISeatVehicle) obj).TurnOffPassengersCollisions();
}
Vector vTemp = null;
if (obj != null)
vTemp = obj.GetUpVector();
else
vTemp = new Vector(Vector.Up);
vTemp.Mul(100f);
vTemp.Add(vStart);
TraceForCollision(vTemp, vStart, null);
// w vStart mamy miejsce, na ktorym "stoi jeep", nie jakies gowno podziemne
vStart.fY += 150f;
cMesh.SetPositionWorld(vStart);
vEnd.Sub(vStart);
cMesh.MoveByEllipsoidPure(vEnd);
float fDist = vEnd.Len();
float fCurrTime = GetTime();
if (fDist <= fLastClipDist)
fLastClipDist = fDist;
else
{
float fDiff = fDist - fLastClipDist;
float fDistToMove = fCameraBackSpeed * (fCurrTime - fLastClipUpdateTime);
if (fDistToMove > fDiff)
fDistToMove = fDiff;
fLastClipDist += fDistToMove;
vEnd.Normalize();
vEnd.Mul(fLastClipDist);
}
vEnd.Add(vStart);
fLastClipUpdateTime = fCurrTime;
// przywracamy kolizje
if (obj != null)
{
obj.SetFlags(iOwnerFlags);
if (obj instanceof ISeatVehicle)
((ISeatVehicle) obj).TurnOnPassengersCollisions();
}
if (vEnd.fY > TerrainHeight(vEnd.fX, vEnd.fZ) &&
vEnd.fY < GetModule().GetWaterLevel())
vEnd.fY = GetModule().GetWaterLevel() + 10;
return vEnd;
}
Vector m_vStartGunDir = new Vector(Vector.Forward);
boolean m_bUseGyro = false;
boolean m_bAimingAllowed = false;
float m_fCamPosChangeSpeed = 3f;
float m_fGunDirDelay = 0.1f;
float m_fAngleH = 0;
float m_fAngleV = 0;
/** Kamera znad ciezkiej broni na pojezdzie, budynku itp.
*/
public class ModeHeavyGun extends State
{
boolean bAiming = false;
float m_fLastFrameTime = 0;
float fCamPosChangeDir = 0;
float fCamPosIndex = 1;
public void OnEnter()
{
if (m_HeavyWeapon == null || m_WeaponOwner == null)
{
CrashLog("Mode heavy gun error !!!, m_HeavyWeapon:" + m_HeavyWeapon + ", m_WeaponOwner:" + m_WeaponOwner + "\n");
return;
}
m_fLastFrameTime = GetTime();
nCurrentMode = CMODE_HEAVYGUN;
m_vGunLookDir = m_WeaponOwner.GetForwardVector(); // chcemy patrzec "w przod" obiektu
// ustawiamy poczatkowa kamere
Vector vTemp = new Vector(m_vGunLookDir);
vTemp.Negate();
FromForwardUpPos(vTemp, m_WeaponOwner.GetUpVector(), GetPosition());
m_vOldUp = GetUpVector();
m_vOldForward = vTemp;
PrepareCameraEllipsoid();
// ustawiamy nowa pozycje kamery wzgledem dzialka
m_fOldOverObservedHeight = m_fOverObservedHeight;
m_fOldOverObservedBack = m_fOverObservedBack;
m_fOverObservedHeight = m_fOverGunHeight;
m_fOverObservedBack = m_fOverGunBack;
SetCamPosDir(m_HeavyWeapon.GetFireOrigin(), m_vGunLookDir);
PrepareYSpring();
}
float fLastPosDirUpdateTime = 0;
void SetCamPosDir(Vector vPos, Vector vDir)
{
float fInert = 1.f;
float fTime = m_fLastFrameTime;
if (fLastPosDirUpdateTime > 0.001f)
{
float fDelay = fTime - fLastPosDirUpdateTime;
if (fDelay < 1e-6f)
fDelay = 1e-6f;
fInert = m_fGunDirDelay / fDelay;
if (fInert < 1.f)
fInert = 1.f;
}
fLastPosDirUpdateTime = fTime;
Vector vCamBaseX = new Vector();
Vector vCamBaseY = new Vector();
Vector vCamBaseZ = new Vector();
vDir.Negate();
vDir.Normalize();
vCamBaseZ.Set(vDir);
float fDot = Vector.Up.Dot(vCamBaseZ);
if ( (fDot >= 1f) || (fDot <= -1f) )
vCamBaseX = GetRightVector();
else
vCamBaseX.Set(Vector.Up.Cross(vCamBaseZ));
vCamBaseX.Normalize();
vCamBaseY = vCamBaseZ.Cross(vCamBaseX);
vCamBaseY.Normalize();
if ( (fDot >= 1f) || (fDot <= -1f) )
{
vCamBaseX = RotateVector(vCamBaseX, m_fAngleH, vCamBaseZ);
vCamBaseY = RotateVector(vCamBaseY, m_fAngleH, vCamBaseZ);
}
else
{
vCamBaseX = RotateVector(vCamBaseX, m_fAngleH, Vector.Up);
vCamBaseY = RotateVector(vCamBaseY, m_fAngleH, Vector.Up);
vCamBaseZ = RotateVector(vCamBaseZ, m_fAngleH, Vector.Up);
}
vCamBaseY = RotateVector(vCamBaseY, -m_fAngleV, vCamBaseX);
vCamBaseZ = RotateVector(vCamBaseZ, -m_fAngleV, vCamBaseX);
Vector vOldCamBaseZ = GetForwardVector();
vCamBaseZ.fX = m_vOldForward.fX + (vCamBaseZ.fX - m_vOldForward.fX) / fInert;
vCamBaseZ.fY = m_vOldForward.fY + (vCamBaseZ.fY - m_vOldForward.fY) / fInert;
vCamBaseZ.fZ = m_vOldForward.fZ + (vCamBaseZ.fZ - m_vOldForward.fZ) / fInert;
Vector vOldCamBaseY = GetUpVector();
vCamBaseY.fX = m_vOldUp.fX + (vCamBaseY.fX - m_vOldUp.fX) / fInert;
vCamBaseY.fY = m_vOldUp.fY + (vCamBaseY.fY - m_vOldUp.fY) / fInert;
vCamBaseY.fZ = m_vOldUp.fZ + (vCamBaseY.fZ - m_vOldUp.fZ) / fInert;
Vector vTemp = new Vector(vPos);
vPos.fY += m_fOverObservedHeight;
vDir.Set(vCamBaseZ);
vDir.Mul(m_fOverObservedBack);
vPos.Add(vDir);
vCamBaseZ = ShakeCameraDir(vCamBaseZ, 0.2f);
vPos = ShakeCameraPos(vPos);
// przycinamy kamere
if (Target.GetSeat() != null)
{
ControlObject occupied = (ControlObject) Target.GetSeat().GetOccupiedObject();
vPos = ClipCamera(vTemp, vPos, occupied);
}
float fSpringCorrection = UpdateCameraY(vPos);
if (fSpringCorrection > m_fOverObservedHeight * 0.5f)
fSpringCorrection = m_fOverObservedHeight * 0.5f;
vPos.fY += fSpringCorrection;
FromForwardUpPos(vCamBaseZ, vCamBaseY, vPos);
m_vOldUp.Set(vCamBaseY);
m_vOldForward.Set(vCamBaseZ);
}
float fLastCamPosIndexUpdateTime = -1;
Vector vCurrPos = new Vector();
Vector vCurrDir = new Vector();
Vector vCurrUp = new Vector();
Vector vTempDir = new Vector();
Vector vTempUp = new Vector();
public void OnPostUpdate()
{
if (m_HeavyWeapon == null || m_WeaponOwner == null)
{
CrashLog("Mode heavy gun OnPostUpdate error !!!, m_HeavyWeapon:" + m_HeavyWeapon + ", m_WeaponOwner:" + m_WeaponOwner + "\n");
return;
}
m_fLastFrameTime = GetTime();
UpdateCameraSprings();
UpdateCameraZoom();
float fTime = m_fLastFrameTime;
float fDeltaTime = (fLastCamPosIndexUpdateTime > 0) ?
fTime - fLastCamPosIndexUpdateTime :
0;
fLastCamPosIndexUpdateTime = fTime;
fCamPosIndex += fCamPosChangeDir * fDeltaTime;
if (fCamPosIndex > 1)
{
fCamPosChangeDir = 0;
fCamPosIndex = 1;
}
else
if (fCamPosIndex < 0)
fCamPosChangeDir = fCamPosIndex = 0;
float fSmoothIdx = Tools.InterpSmoothstep(0, 1, fCamPosIndex);
Vector vHeavyGunCenter = m_HeavyWeapon.GetCannonOrigin();
if (m_bAimingAllowed)
{
m_fOverObservedHeight = m_fOverGunHeightAim +
(m_fOverGunHeight - m_fOverGunHeightAim) *
fSmoothIdx;
m_fOverObservedBack = m_fOverGunBackAim +
(m_fOverGunBack - m_fOverGunBackAim) *
fSmoothIdx;
}
else
{
float fFOV = m_fOverGunAimFOV + (m_fOverGunFOV - m_fOverGunAimFOV) * fSmoothIdx;
SetFOV(fFOV);
}
if (!m_bUseGyro)
m_vGunLookDir = m_WeaponOwner.GetForwardVector();
else
m_vGunLookDir = new Vector(m_vStartGunDir);
VehicleAttacker attacker = null;
if (m_WeaponOwner instanceof VehicleAttacker)
{
attacker = (VehicleAttacker) m_WeaponOwner;
attacker.GetRenderPosition(vHeavyGunCenter, vTempDir, vTempUp);
vTempDir.CrossStatic(vTempUp, vTempUp);
// dodajemy przesuniecie centrum dzialka wzgledem pozycji pojazdu
Vector vLocalDiff = attacker.cCannon.GetCannonToParentPositionDiff();
vLocalDiff.fY -= _HEAVY_GUN_CAM_PIVOT_CORRECTION; // obnizenie punktu obrotu kamery
attacker.GetPosition(vCurrPos);
attacker.GetForwardVector(vCurrDir);
attacker.GetUpVector(vCurrUp);
attacker.FromUpForwardPos(vTempUp, vTempDir, vHeavyGunCenter);
vHeavyGunCenter.Add(attacker.VectorLocalToWorld(vLocalDiff));
}
else
vHeavyGunCenter.fY -= _HEAVY_GUN_CAM_PIVOT_CORRECTION; // obnizenie punktu obrotu kamery
SetCamPosDir(vHeavyGunCenter, m_vGunLookDir);
m_HeavyWeapon.AimAtPoint(GetTargetPoint((MeshObject) m_HeavyWeapon.GetOwnerMesh()));
if (attacker != null)
attacker.FromUpForwardPos(vCurrUp, vCurrDir, vCurrPos);
UpdatePlayerSpeaker();
}
//*********************************************************
// SaveGame
//*********************************************************
public void SGLoad(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer$ModeHeavyGun] : SGLoad\n");
FileChunk cFC = GameObject.LoadChunk(cParentFC);
if (cFC.GetID() == ESGChunksChrome._CHK_CAMERA_PLAYER_MODE_HEAVY_GUN_STATE)
{
super.SGLoad(cFC);
m_fAngleH = cFC.LoadFloat();
m_fAngleV = cFC.LoadFloat();
bAiming = cFC.LoadBool();
m_fLastFrameTime = cFC.LoadFloat();
fCamPosChangeDir = cFC.LoadFloat();
fCamPosIndex = cFC.LoadFloat();
fLastPosDirUpdateTime = cFC.LoadFloat();
fLastCamPosIndexUpdateTime = cFC.LoadFloat();
}
cFC.delete();
}
public void SGSave(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer$ModeHeavyGun] : SGSave\n");
FileChunk cFC = NewChunk(ESGChunksChrome._CHK_CAMERA_PLAYER_MODE_HEAVY_GUN_STATE, cParentFC);
super.SGSave(cFC);
cFC.SaveFloat(m_fAngleH);
cFC.SaveFloat(m_fAngleV);
cFC.SaveBool(bAiming);
cFC.SaveFloat(m_fLastFrameTime);
cFC.SaveFloat(fCamPosChangeDir);
cFC.SaveFloat(fCamPosIndex);
cFC.SaveFloat(fLastPosDirUpdateTime);
cFC.SaveFloat(fLastCamPosIndexUpdateTime);
cFC.delete();
}
public void SGUpdate()
{
FileChunk.Log("[CameraPlayer$ModeHeavyGun] : SGUpdate\n");
nCurrentMode = CMODE_HEAVYGUN;
PrepareCameraEllipsoid();
SetCamPosDir(m_HeavyWeapon.GetFireOrigin(), m_vGunLookDir);
OnPostUpdate();
}
public void OnInputMouseButton(int nButton, int nState)
{
CallOnInputKey(Player.ConvertMouseButtonToKey(nButton), nState, '0');
}
void OnInputMouseAxis(int nAxis, int nDelta)
{
if (Game.cSingleton.IsScreenShotMode()) return;
if ( ((PlayerHUD) Target).HUD.GetHUDMap().bActiveFlag ) return; // jezeli mapa wlaczona, to nie reagujemy
switch (nAxis)
{
case EMouse._AXIS_X:
{
if (m_HeavyWeapon != null)
{
m_fAngleH += (float)nDelta * ControlLoadSave.fMouseSensitivity * m_fGunMouseSensitivityMul;
if (m_HeavyWeapon.GetMaxHorizAngle() < 180) // jest ograniczenie
{
if (m_fAngleH > m_HeavyWeapon.GetMaxHorizAngle())
m_fAngleH = m_HeavyWeapon.GetMaxHorizAngle();
if (m_fAngleH < -m_HeavyWeapon.GetMaxHorizAngle())
m_fAngleH = -m_HeavyWeapon.GetMaxHorizAngle();
}
else //zrob tylko modulo
{
int nTimez = (int)(m_fAngleH / 360.f);
m_fAngleH -= nTimez * 360.f;
}
}
}
break;
case EMouse._AXIS_Y:
{
if (m_HeavyWeapon != null)
{
float fInvert = ControlLoadSave.Invert_Mouse ? -1.f : 1.f;
m_fAngleV -= nDelta * fInvert * ControlLoadSave.fMouseSensitivity * m_fGunMouseSensitivityMul;
if (m_fAngleV > m_HeavyWeapon.GetMaxVertAngle())
m_fAngleV = m_HeavyWeapon.GetMaxVertAngle();
if (m_fAngleV < m_HeavyWeapon.GetMinVertAngle())
m_fAngleV = m_HeavyWeapon.GetMinVertAngle();
//LogLine("CameraGun nDelta:"+nDelta+" m_fAngleV:"+m_fAngleV+" max:"+m_HeavyWeapon.m_fMaxVAngle+" min:"+m_HeavyWeapon.m_fMinVAngle);
}
}
break;
case EMouse._AXIS_Z:
HUDManager.ProcessMouseWheel(CameraPlayer.this, nAxis, nDelta);
break;
}
}
void OnInputKey(int nKeyCode, boolean bKeyState, char nKeyAscii)
{
// jezeli mapa wlaczona, to nie reagujemy
if ( ((PlayerHUD) Target).HUD.GetHUDMap().bActiveFlag )
return;
if ( (nKeyCode == EGameControl.AIM) || (nKeyCode == EGameControl.AIM_BY_TOGGLE) )
{
if (bAiming != bKeyState) //zmiana
{
bAiming = bKeyState;
if (bAiming)
fCamPosChangeDir = -m_fCamPosChangeSpeed;
else
fCamPosChangeDir = m_fCamPosChangeSpeed;
}
}
/*
if ((m_HeavyWeapon != null) && (nKeyCode == EGameControl.AIM) )
{
if (bKeyState)
{
Target.DisableCallMethod("StartAiming");
Target.CallMethodIn("StartAiming", 0f);
}
else
{
Target.DisableCallMethod("StopAiming");
Target.CallMethodIn("StopAiming", 0f);
}
}
*/
}
}
Walker m_cWalker = null;
float m_fOverWalkerBack = 500.0f;
float m_fOverWalkerHeight = 600.0f;
/** Kamera za walkerem:
* o zachowuje bezwladnosc
* o umozliwia celowanie
*/
public class ModeWalker extends State
{
float m_fAngleH;
float m_fAngleV;
float m_fLastFrameTime = 0;
float fCamPosChangeDir = 0;
float fCamPosIndex = 1;
Vector m_cWalkerPos = null;
public void OnEnter()
{
m_cWalkerPos = new Vector();
m_cWalker = null;
if ( (Target != null) && (Target.cSeatInfo != null) &&
(Target.cSeatInfo.GetOccupiedObject() instanceof Walker) )
{
m_cWalker = (Walker)Target.cSeatInfo.GetOccupiedObject();
}
nCurrentMode = CMODE_WALKER;
if (m_cWalker != null)
m_vGunLookDir = m_cWalker.GetForwardVector();
m_vOldUp = GetUpVector();
m_vOldForward = GetForwardVector();
SetCamPosDir( m_cWalker.GetFireOrigin(), m_vGunLookDir );
m_fAngleH = 0f;
m_fAngleV = 0f;
m_fOldOverObservedHeight = m_fOverObservedHeight;
m_fOldOverObservedBack = m_fOverObservedBack;
// ustawiamy nowa pozycje kamery wzgledem walkera
m_fOverObservedHeight = m_fOverWalkerHeight;
m_fOverObservedBack = m_fOverWalkerBack;
}
float fLastPosDirUpdateTime = 0;
void SetCamPosDir(Vector vPos, Vector vDir)
{
float fInert = 1.f;
float fTime = m_fLastFrameTime;
if (fLastPosDirUpdateTime > 0.001f)
{
float fDelay = fTime - fLastPosDirUpdateTime;
if (fDelay < 1e-6f)
fDelay = 1e-6f;
fInert = m_fGunDirDelay / fDelay;
if (fInert < 1.f)
fInert = 1.f;
}
fLastPosDirUpdateTime = fTime;
Vector vCamBaseX = new Vector();
Vector vCamBaseY = new Vector();
Vector vCamBaseZ = new Vector();
vDir.Negate();
vDir.Normalize();
vCamBaseZ.Set(vDir);
float fDot = Vector.Up.Dot(vCamBaseZ);
if ( (fDot >= 1f) || (fDot <= -1f) )
vCamBaseX = GetRightVector();
else
vCamBaseX.Set(Vector.Up.Cross(vCamBaseZ));
vCamBaseX.Normalize();
vCamBaseY = vCamBaseZ.Cross(vCamBaseX);
vCamBaseY.Normalize();
if ( (fDot >= 1f) || (fDot <= -1f) )
{
vCamBaseX = RotateVector(vCamBaseX, m_fAngleH, vCamBaseZ);
vCamBaseY = RotateVector(vCamBaseY, m_fAngleH, vCamBaseZ);
}
else
{
vCamBaseX = RotateVector(vCamBaseX, m_fAngleH, Vector.Up);
vCamBaseY = RotateVector(vCamBaseY, m_fAngleH, Vector.Up);
vCamBaseZ = RotateVector(vCamBaseZ, m_fAngleH, Vector.Up);
}
vCamBaseY = RotateVector(vCamBaseY, -m_fAngleV, vCamBaseX);
vCamBaseZ = RotateVector(vCamBaseZ, -m_fAngleV, vCamBaseX);
Vector vOldCamBaseZ = GetForwardVector();
vCamBaseZ.fX = m_vOldForward.fX + (vCamBaseZ.fX - m_vOldForward.fX) / fInert;
vCamBaseZ.fY = m_vOldForward.fY + (vCamBaseZ.fY - m_vOldForward.fY) / fInert;
vCamBaseZ.fZ = m_vOldForward.fZ + (vCamBaseZ.fZ - m_vOldForward.fZ) / fInert;
Vector vOldCamBaseY = GetUpVector();
vCamBaseY.fX = m_vOldUp.fX + (vCamBaseY.fX - m_vOldUp.fX) / fInert;
vCamBaseY.fY = m_vOldUp.fY + (vCamBaseY.fY - m_vOldUp.fY) / fInert;
vCamBaseY.fZ = m_vOldUp.fZ + (vCamBaseY.fZ - m_vOldUp.fZ) / fInert;
vPos.fY += m_fOverObservedHeight;
vDir.Set(vCamBaseZ);
vDir.Mul(m_fOverObservedBack);
vPos.Add(vDir);
vPos = ShakeCameraPos(vPos);
FromForwardUpPos(ShakeCameraDir(vCamBaseZ, 0.2f), vCamBaseY, vPos);
m_vOldUp.Set(vCamBaseY);
m_vOldForward.Set(vCamBaseZ);
}
float fLastCamPosIndexUpdateTime = -1;
public void OnPostUpdate()
{
m_fLastFrameTime = GetTime();
UpdateCameraSprings();
UpdateCameraZoom();
if (m_cWalker != null)
{
float fTime = m_fLastFrameTime;
float fDeltaTime = (fLastCamPosIndexUpdateTime > 0) ?
fTime - fLastCamPosIndexUpdateTime :
0;
fLastCamPosIndexUpdateTime = fTime;
fCamPosIndex += fCamPosChangeDir * fDeltaTime;
if (fCamPosIndex > 1)
{
fCamPosChangeDir = 0;
fCamPosIndex = 1;
}
else if (fCamPosIndex < 0)
fCamPosChangeDir = fCamPosIndex = 0;
float fSmoothIdx = Tools.InterpSmoothstep(0, 1, fCamPosIndex);
m_vGunLookDir = m_cWalker.GetForwardVector();
m_cWalker.GetRenderPosition( m_cWalkerPos, null, null );
m_cWalkerPos.fY -= _HEAVY_GUN_CAM_PIVOT_CORRECTION; // obnizenie punktu obrotu kamery
SetCamPosDir( m_cWalkerPos, m_vGunLookDir );
m_cWalker.SetTargetPoint( GetTargetPoint( m_cWalker) );
}
UpdatePlayerSpeaker();
}
public void OnInputMouseButton(int nButton, int nState)
{
if (ChromeGame.cSingleton instanceof ChromeGame)
{
ChromeGame game = (ChromeGame) ChromeGame.cSingleton;
if ( (game.Menu != null) && (game.Menu.bInGameMenuAct) )
return;
}
CallOnInputKey(Player.ConvertMouseButtonToKey(nButton), nState, '0');
}
void OnInputKey(int nKeyCode, boolean bKeyState, char nKeyAscii)
{
// jezeli mapa wlaczona, to nie reagujemy, tak samo z voice menu
if ( ((PlayerHUD) Target).HUD.GetHUDMap().bActiveFlag ||
((PlayerHUD) Target).IsActiveVoiceMenu())
return;
if ( m_cWalker == null )
return;
if ( nKeyCode == EGameControl.FIRE )
m_cWalker.SetFire( WeaponWalker._MODE_PRIMARY , bKeyState );
else
if ( nKeyCode == EGameControl.AIM ||
nKeyCode == EGameControl.AIM_BY_TOGGLE ||
nKeyCode == EGameControl.AIM_TOGGLE)
m_cWalker.SetFire( WeaponWalker._MODE_SECONDARY , bKeyState );
}
void OnInputMouseAxis(int nAxis, int nDelta)
{
if (Game.cSingleton.IsScreenShotMode())
return;
// jezeli mapa wlaczona, to nie reagujemy
if ( ((PlayerHUD) Target).HUD.GetHUDMap().bActiveFlag )
return;
if (m_cWalker == null)
return;
switch (nAxis)
{
case EMouse._AXIS_X:
{
m_fAngleH += (float)nDelta * ControlLoadSave.fMouseSensitivity * m_fGunMouseSensitivityMul;
if (m_fAngleH > m_cWalker.GetMaxHorizAngle())
m_fAngleH = m_cWalker.GetMaxHorizAngle();
if (m_fAngleH < -m_cWalker.GetMaxHorizAngle())
m_fAngleH = -m_cWalker.GetMaxHorizAngle();
}
break;
case EMouse._AXIS_Y:
{
float fInvert = ControlLoadSave.Invert_Mouse ? -1.f : 1.f;
m_fAngleV -= nDelta * fInvert * ControlLoadSave.fMouseSensitivity * m_fGunMouseSensitivityMul;
if (m_fAngleV > m_cWalker.GetMaxVertAngle())
m_fAngleV = m_cWalker.GetMaxVertAngle();
if (m_fAngleV < m_cWalker.GetMinVertAngle())
m_fAngleV = m_cWalker.GetMinVertAngle();
}
break;
case EMouse._AXIS_Z:
{
HUDManager.ProcessMouseWheel(CameraPlayer.this, nAxis, nDelta);
}
break;
}
m_cWalker.RotateHead( m_fAngleH, m_fAngleV );
}
//*********************************************************
// SaveGame
//*********************************************************
public void SGLoad(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer$ModeWalker] : SGLoad\n");
FileChunk cFC = GameObject.LoadChunk(cParentFC);
if (cFC.GetID() == ESGChunksChrome._CHK_CAMERA_PLAYER_MODE_WALKER_STATE)
{
super.SGLoad(cFC);
m_fAngleH = cFC.LoadFloat();
m_fAngleV = cFC.LoadFloat();
m_fLastFrameTime = cFC.LoadFloat();
fCamPosChangeDir = cFC.LoadFloat();
fCamPosIndex = cFC.LoadFloat();
fLastPosDirUpdateTime = cFC.LoadFloat();
fLastCamPosIndexUpdateTime = cFC.LoadFloat();
}
cFC.delete();
}
public void SGSave(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer$ModeWalker] : SGSave\n");
FileChunk cFC = NewChunk(ESGChunksChrome._CHK_CAMERA_PLAYER_MODE_WALKER_STATE, cParentFC);
super.SGSave(cFC);
cFC.SaveFloat(m_fAngleH);
cFC.SaveFloat(m_fAngleV);
cFC.SaveFloat(m_fLastFrameTime);
cFC.SaveFloat(fCamPosChangeDir);
cFC.SaveFloat(fCamPosIndex);
cFC.SaveFloat(fLastPosDirUpdateTime);
cFC.SaveFloat(fLastCamPosIndexUpdateTime);
cFC.delete();
}
public void SGUpdate()
{
FileChunk.Log("[CameraPlayer$ModeWalker] : SGUpdate\n");
m_cWalker = null;
if ( (Target != null) && (Target.cSeatInfo != null) &&
(Target.cSeatInfo.GetOccupiedObject() instanceof Walker) )
{
m_cWalker = (Walker)Target.cSeatInfo.GetOccupiedObject();
}
nCurrentMode = CMODE_WALKER;
SetCamPosDir( m_cWalker.GetFireOrigin(), m_vGunLookDir );
}
}
/** Kamera znad ciezkiej broni na pojezdzie, budynku itp.
*/
public class ModeVehiclePassenger extends State
{
float m_fLastFrameTime = 0;
float fCamPosChangeDir = 0;
float fCamPosIndex = 1;
Vehicle m_Vehicle = null;
public void OnEnter()
{
if ( (Target == null) ||
(Target.GetSeat() == null) ||
(!(Target.GetSeat().GetOccupiedObject() instanceof Vehicle)) )
{
CrashLog("ERROR: Camera Mode VehiclePassenger !!!\n");
return;
}
m_Vehicle = (Vehicle)Target.GetSeat().GetOccupiedObject();
m_fLastFrameTime = GetTime();
nCurrentMode = CMODE_VEHICLE_PASSENGER;
// ustawiamy poczatkowa kamere
Vector vTemp = new Vector(m_Vehicle.GetForwardVector());
vTemp.Negate();
FromForwardUpPos(vTemp, m_Vehicle.GetUpVector(), GetPosition());
m_vOldUp = GetUpVector();
m_vOldForward = vTemp;
m_fAngleH = m_fAngleV = 0.0f;
PrepareCameraEllipsoid();
// ustawiamy nowa pozycje kamery wzgledem dzialka
m_fOldOverObservedHeight = m_fOverObservedHeight;
m_fOldOverObservedBack = m_fOverObservedBack;
//?
m_fOverObservedHeight = m_fOverGunHeight;
m_fOverObservedBack = m_fOverGunBack;
SetCamPosDir( m_Vehicle.GetPosition(), m_Vehicle.GetForwardVector());
PrepareYSpring();
}
float fLastPosDirUpdateTime = 0;
void SetCamPosDir(Vector vPos, Vector vDir)
{
float fInert = 1.f;
float fTime = m_fLastFrameTime;
if (fLastPosDirUpdateTime > 0.001f)
{
float fDelay = fTime - fLastPosDirUpdateTime;
if (fDelay < 1e-6f)
fDelay = 1e-6f;
fInert = m_fGunDirDelay / fDelay;
if (fInert < 1.f)
fInert = 1.f;
}
fLastPosDirUpdateTime = fTime;
Vector vCamBaseX = new Vector();
Vector vCamBaseY = new Vector();
Vector vCamBaseZ = new Vector();
vDir.Negate();
vDir.Normalize();
vCamBaseZ.Set(vDir);
float fDot = Vector.Up.Dot(vCamBaseZ);
if ( (fDot >= 1f) || (fDot <= -1f) )
vCamBaseX = GetRightVector();
else
vCamBaseX.Set(Vector.Up.Cross(vCamBaseZ));
vCamBaseX.Normalize();
vCamBaseY = vCamBaseZ.Cross(vCamBaseX);
vCamBaseY.Normalize();
if ( (fDot >= 1f) || (fDot <= -1f) )
{
vCamBaseX = RotateVector(vCamBaseX, m_fAngleH, vCamBaseZ);
vCamBaseY = RotateVector(vCamBaseY, m_fAngleH, vCamBaseZ);
}
else
{
vCamBaseX = RotateVector(vCamBaseX, m_fAngleH, Vector.Up);
vCamBaseY = RotateVector(vCamBaseY, m_fAngleH, Vector.Up);
vCamBaseZ = RotateVector(vCamBaseZ, m_fAngleH, Vector.Up);
}
vCamBaseY = RotateVector(vCamBaseY, -m_fAngleV, vCamBaseX);
vCamBaseZ = RotateVector(vCamBaseZ, -m_fAngleV, vCamBaseX);
Vector vOldCamBaseZ = GetForwardVector();
vCamBaseZ.fX = m_vOldForward.fX + (vCamBaseZ.fX - m_vOldForward.fX) / fInert;
vCamBaseZ.fY = m_vOldForward.fY + (vCamBaseZ.fY - m_vOldForward.fY) / fInert;
vCamBaseZ.fZ = m_vOldForward.fZ + (vCamBaseZ.fZ - m_vOldForward.fZ) / fInert;
Vector vOldCamBaseY = GetUpVector();
vCamBaseY.fX = m_vOldUp.fX + (vCamBaseY.fX - m_vOldUp.fX) / fInert;
vCamBaseY.fY = m_vOldUp.fY + (vCamBaseY.fY - m_vOldUp.fY) / fInert;
vCamBaseY.fZ = m_vOldUp.fZ + (vCamBaseY.fZ - m_vOldUp.fZ) / fInert;
Vector vTemp = new Vector(vPos);
vPos.fY += m_fOverObservedHeight;
vDir.Set(vCamBaseZ);
vDir.Mul(m_fOverObservedBack);
vPos.Add(vDir);
vCamBaseZ = ShakeCameraDir(vCamBaseZ, 0.2f);
vPos = ShakeCameraPos(vPos);
// przycinamy kamere
vPos = ClipCamera(vTemp, vPos, m_Vehicle);
float fSpringCorrection = UpdateCameraY(vPos);
if (fSpringCorrection > m_fOverObservedHeight * 0.5f)
fSpringCorrection = m_fOverObservedHeight * 0.5f;
vPos.fY += fSpringCorrection;
FromForwardUpPos(vCamBaseZ, vCamBaseY, vPos);
m_vOldUp.Set(vCamBaseY);
m_vOldForward.Set(vCamBaseZ);
}
float fLastCamPosIndexUpdateTime = -1;
Vector vCurrPos = new Vector();
Vector vCurrDir = new Vector();
Vector vCurrUp = new Vector();
Vector vTempDir = new Vector();
Vector vTempUp = new Vector();
Vector m_vCamPos = new Vector();
Vector m_vCamDir = new Vector();
public void OnPostUpdate()
{
m_fLastFrameTime = GetTime();
UpdateCameraSprings();
UpdateCameraZoom();
float fTime = m_fLastFrameTime;
float fDeltaTime = (fLastCamPosIndexUpdateTime > 0) ?
fTime - fLastCamPosIndexUpdateTime :
0;
fLastCamPosIndexUpdateTime = fTime;
fCamPosIndex += fCamPosChangeDir * fDeltaTime;
if (fCamPosIndex > 1)
{
fCamPosChangeDir = 0;
fCamPosIndex = 1;
}
else
if (fCamPosIndex < 0)
fCamPosChangeDir = fCamPosIndex = 0;
float fSmoothIdx = Tools.InterpSmoothstep(0, 1, fCamPosIndex);
SetFOV( m_fOverGunAimFOV + (m_fOverGunFOV - m_fOverGunAimFOV) * fSmoothIdx );
//TODO: przeanalizowac ile z tego jest potrzebne
m_vCamPos = m_Vehicle.GetPosition();
m_vCamDir = m_Vehicle.GetForwardVector();
m_Vehicle.GetRenderPosition( m_vCamPos, vTempDir, vTempUp );
vTempDir.CrossStatic( vTempUp, vTempUp );
// dodajemy przesuniecie w gore wzgledem pozycji pojazdu
Vector vLocalDiff = new Vector( 0, 450.0f , 0 );
m_Vehicle.GetPosition( vCurrPos );
m_Vehicle.GetForwardVector( vCurrDir );
m_Vehicle.GetUpVector( vCurrUp );
m_Vehicle.FromUpForwardPos( vTempUp, vTempDir, m_vCamPos );
m_vCamPos.Add( m_Vehicle.VectorLocalToWorld( vLocalDiff ) );
SetCamPosDir( m_vCamPos, m_vCamDir );
m_Vehicle.FromUpForwardPos(vCurrUp, vCurrDir, vCurrPos);
UpdatePlayerSpeaker();
//zmieniam kierunek gracza, zeby na kompasie bylo widac
//jak sie obraca.
//uwaga: na mapie kierunek gracza tez sie zmieni i
//jest to pewna niekonsekwencja w stosunku do jeepa,
//gdzie gunner mimo ze sie obraca, to jest "strzalka"
//zawsze pokazuje kierunak pojazdu
m_vTargetDir.Set( m_vCamDir );
m_vTargetDir.Negate();
Target.SetDir( m_vTargetDir );
}
Vector m_vTargetDir = new Vector();
/**
* Tryb wykorzystywany tylko w sieci, zatem
* nie potrzeba obslugiwac save'ow.
* Jesli cos by sie mialo w tej kwestii zmienic
* to dopisac
*/
public void SGLoad(FileChunk cParentFC)
{
}
public void SGSave(FileChunk cParentFC)
{
}
public void SGUpdate()
{
}
public void OnInputMouseButton(int nButton, int nState)
{
CallOnInputKey(Player.ConvertMouseButtonToKey(nButton), nState, '0');
}
float m_fMinVertAngle = -10.0f;
float m_fMaxVertAngle = 60.0f;
void OnInputMouseAxis(int nAxis, int nDelta)
{
if (Game.cSingleton.IsScreenShotMode()) return;
if ( ((PlayerHUD) Target).HUD.GetHUDMap().bActiveFlag ) return; // jezeli mapa wlaczona, to nie reagujemy
switch (nAxis)
{
case EMouse._AXIS_X:
{
m_fAngleH += (float)nDelta * ControlLoadSave.fMouseSensitivity*m_fGunMouseSensitivityMul;
int nTimez = (int)(m_fAngleH / 360.f);
m_fAngleH -= nTimez * 360.f;
}
break;
case EMouse._AXIS_Y:
{
float fInvert = ControlLoadSave.Invert_Mouse ? -1.f : 1.f;
m_fAngleV -= nDelta * fInvert * ControlLoadSave.fMouseSensitivity*m_fGunMouseSensitivityMul;
if (m_fAngleV > m_fMaxVertAngle)
m_fAngleV = m_fMaxVertAngle;
if (m_fAngleV < m_fMinVertAngle)
m_fAngleV = m_fMinVertAngle;
}
break;
case EMouse._AXIS_Z:
HUDManager.ProcessMouseWheel(CameraPlayer.this, nAxis, nDelta);
break;
}
}
void OnInputKey(int nKeyCode, boolean bKeyState, char nKeyAscii)
{
}
}
/** Ustawienie trybu pracy kamery
*/
public void SetMode(byte nMode)
{
if (nMode != nCurrentMode) //zeby uniknac wielokrotnego OnEnter
{
Log("Changing camera state to: " + aModes[nMode] + "\n");
nLastMode = nCurrentMode;
Target.CameraModeChanged(nMode);
SetState(aModes[nMode]);
}
//TODO: zrobic osobna klase CameraPlayerNet
if (Target instanceof PlayerNet)
{
((PlayerNet)Target).nCurrentViewMode = nMode;
}
}
/** Pobranie trybu pracy kamery
*/
public byte GetMode()
{
return nCurrentMode;
}
/** Ustawienie ujecia (take - ujecie)
*/
public void SetTake(MotionState motion, boolean bSmooth)
{
fOldHeight = fCurHeight;
if( (nCurrentMode == CMODE_FPP) ||
(nCurrentMode == CMODE_SNIPER)
)
{
fNewHeight = fFPPHeightDef[motion.iSpeed];
if (Target.bBurbotMode == true)
{
//printStackTrace("");
fNewHeight += 50;
}
}
else
fNewHeight = fHeightDef[motion.iSpeed];
fOldBackDistance = fCurBackDistance;
fNewBackDistance = fBackDistanceDef[motion.iSpeed];
if (!bSmooth)
{
fCurBackDistance = fNewBackDistance;
fOldBackDistance = fNewBackDistance;
fCurHeight = fNewHeight;
fOldHeight = fNewHeight;
}
fChangeTime = GetTime();
}
public void SetZoom(float fZoom)
{
SetZoomDo(fZoom);
m_fDestZoom = fZoom;
}
public void SetZoomSmooth(float fDestZoom)
{
m_fDestZoom = fDestZoom;
}
private void SetZoomDo(float fZoom)
{
m_fCurZoom = fZoom;
float angle = 360.f / (float)Math.PI * (float)Math.atan(fFovTan[nCurrentMode]/fZoom);
SetFOV(angle);
SetFarZoom(fZoom);
//TODO: zrobic osobna klase CameraPlayerNet
if (Target instanceof PlayerNet)
{
((PlayerNet)Target).fCurrentViewZoom = fZoom;
}
}
float l_fLastZoomUpdate = 0; // not SG
public void UpdateCameraZoom()
{
float fTime = GetTime();
if (l_fLastZoomUpdate == 0)
l_fLastZoomUpdate = fTime;
if (m_fCurZoom < m_fDestZoom)
{
m_fCurZoom += (fTime - l_fLastZoomUpdate) * m_fZoomSpeed;
if (m_fCurZoom > m_fDestZoom)
m_fCurZoom = m_fDestZoom;
}
else
{
if (m_fCurZoom > m_fDestZoom)
{
m_fCurZoom -= (fTime - l_fLastZoomUpdate) * m_fZoomSpeed;
if (m_fCurZoom < m_fDestZoom)
m_fCurZoom = m_fDestZoom;
}
}
l_fLastZoomUpdate = fTime;
SetZoomDo(m_fCurZoom);
}
/** Sprawdza, jak daleko mozna przesunac sie z danego punktu w danym kierunku
* @param vStart wektor poczatkowy (Vector
)
* @param vDir kierunek, w ktorym sie przesuwamy (znormalizowany) (Vector
)
* @param fMaxDistance maksymalna odleglosc, w jakiej wykonuje sie test
* @return odleglosc nie wieksza od fMaxDistance, w ktorej wystapila kolizja
*/
float CheckMaxDistance(Vector vStart, Vector vDir, float fMaxDistance)
{
float fCheckedDistance = fMaxDistance;
// TODO: odremowac, jak beda kolizje perface
/**
// strzelamy wektorem z vStart na odleglosc fMaxDistance
Vector vEnd=new Vector(vDir);
vEnd.Mul(fMaxDistance);
vEnd.Add(vStart);
// najpierw kolizja z terenem
Collision stCollInfo=TraceTerrain(vStart, vEnd);
if (stCollInfo != null)
fCheckedDistance = Math.min(fCheckedDistance, stCollInfo.fDistance);
// teraz kolizje z obiektami
stCollInfo = TraceObjectsExclude(vStart, vEnd, Target);
if(stCollInfo!=null)
fCheckedDistance = Math.min(fCheckedDistance, stCollInfo.fDistance);
*/
return fCheckedDistance;
}
/** Funkcja interpolujaca - zwraca jaka powinna byc znormalizowana wartosc
* wraz z uplywem czasu od fStartTime do GetTimeNow()
* @param fStartTime czas od ktorego nastapila zmiana interpolowanego param. (float
)
* @param fTotalTIme calkowity czas trwania zmiany
* @return wartosc od 0.f (dla poczatku) do 1.f (dla konca zmiany)
*/
float InterpolateMove(float fStartTime, float fTotalTime)
{
float fDeltaTime = GetTime() - fStartTime;
float fEndTime = fStartTime + fTotalTime;
// Jesli poza przedzialem to wrzuc na granice
fDeltaTime = Math.max(fDeltaTime, 0);
fDeltaTime = Math.min(fDeltaTime, fTotalTime);
return 1.f - (float)Math.pow(1.f - fDeltaTime/fTotalTime, 5.f);
}
float fZoom = 1.0f;
float fNearClip = 100.0f;
void OnInputKey(int nKeyCode, boolean bKeyState, char nKeyAscii)
{
/* if(nKeyCode==EKey._F5)
if(bKeyState)
{
fZoom *= 2.f;
Log("fZoom="+ String.valueOf(fZoom)+ "\n");
SetZoom(fZoom);
}
if(nKeyCode==EKey._F6)
if(bKeyState)
{
fZoom /= 2.f;
Log("fZoom="+ String.valueOf(fZoom)+ "\n");
SetZoom(fZoom);
}
*/
if( nKeyCode==EKey._F4 )
if(bKeyState && bTPPEnabled)
{
if(nCurrentMode==CMODE_TPP) SetMode(CMODE_FPP);
else
if(nCurrentMode==CMODE_FPP) SetMode(CMODE_TPP);
}
}
boolean bTPPEnabled = false;
/** @return kat pod ktorym powinnna strzelac bron, zeby trafic w to samo,
* w co celuje kamera.
* @param vCameraTarget punkt, w ktory celuje kamera
*/
float AimAngleCameraToWeapon()
{
//punkt z ktorego strzelamy
Vector vFireOrigin = Target.GetFireOrigin();
//wektor w kierunku punktu, w ktory celujemy
Vector vCameraTarget = GetTargetPoint();
float fTargetY = vCameraTarget.fY;
vCameraTarget.Sub(vFireOrigin);
vCameraTarget.Normalize();
//wektor poziomu
Vector vHoriz = Target.GetForwardVector();
//kat miedzy tym wektorem a poziomem
float fAngle = (float)Math.acos(vCameraTarget.Dot(vHoriz));
//celujemy powyzej czy ponizej?
if (fTargetY < vFireOrigin.fY)
fAngle = -fAngle;
return fAngle;
}
/** Wyliczenie punktu w ktory aktualnie celuje celownik
* @return wektor zawierajacy punkt
*/
Vector GetTargetPoint()
{
return GetTargetPoint( null );
}
/** Wyliczenie punktu w ktory aktualnie celuje celownik,
* dodatkowo pomijany jest obiekt przy traceowaniu
* @param vStart
* @param vDir
* @param cExtraExclude obiekt ktory ma zostac pominietyprzy traceowaniu
* @return wektor zawierajacy punkt
*/
Vector GetTargetPoint(Vector vStart, Vector vDir, MeshObject cExtraExclude)
{
Vector vEnd=new Vector(vDir);
// strzelamy wektorem z kamery na odleglosc fMaxTargetDist
vEnd.Mul(-fMaxTargetDist);
vEnd.Add(vStart);
// sprawdzmy czy mamy kogos pominac przy trace'owaniu
if ( cExtraExclude != null )
{
// czy on ma kolizje wlaczone?
if ( (cExtraExclude.GetFlags() & EFlags._BLOCK_TRACE) != 0 )
{
//tak, wiec wylaczmy mu kolizje na chwilke
cExtraExclude.ClearFlag( EFlags._BLOCK_TRACE );
}
else
{
//nie, zatem mozemy o nim zapomniec...
cExtraExclude = null;
}
}
// liczymy kolizje ze wszystkim po kolei
Collision stCollInfo=TraceTerrain(vStart, vEnd);
stCollInfo=TraceTrees(vStart, vEnd);
stCollInfo=TraceObjectsExclude(vStart, vEnd, Target);
//czy jakiemus obiektowi wylaczylismy kolizje?
if ( cExtraExclude != null )
{
//tak, przywrocmy mu je...
cExtraExclude.SetFlag( EFlags._BLOCK_TRACE );
}
// vEnd zawiera dociety po kolizji punkt
return vEnd;
}
/** Wyliczenie punktu w ktory aktualnie celuje celownik,
* dodatkowo pomijany jest obiekt przy traceowaniu
* @param obiekt ktory ma zostac pominietyprzy traceowaniu
* @return wektor zawierajacy punkt
*
*/
Vector GetTargetPoint(MeshObject cExtraExclude)
{
Vector vStart = GetPosition();
Vector vEnd=new Vector(GetForwardVector());
// strzelamy wektorem z kamery na odleglosc fMaxTargetDist
vEnd.Mul(-fMaxTargetDist);
vEnd.Add(vStart);
// sprawdzmy czy mamy kogos pominac przy trace'owaniu
if ( cExtraExclude != null )
{
// czy on ma kolizje wlaczone?
if ( (cExtraExclude.GetFlags() & EFlags._BLOCK_TRACE) != 0 )
{
//tak, wiec wylaczmy mu kolizje na chwilke
cExtraExclude.ClearFlag( EFlags._BLOCK_TRACE );
}
else
{
//nie, zatem mozemy o nim zapomniec...
cExtraExclude = null;
}
}
// liczymy kolizje ze wszystkim po kolei
Collision stCollInfo=TraceTerrain(vStart, vEnd);
stCollInfo=TraceTrees(vStart, vEnd);
stCollInfo=TraceObjectsExclude(vStart, vEnd, Target);
//czy jakiemus obiektowi wylaczylismy kolizje?
if ( cExtraExclude != null )
{
//tak, przywrocmy mu je...
cExtraExclude.SetFlag( EFlags._BLOCK_TRACE );
}
// vEnd zawiera dociety po kolizji punkt
return vEnd;
}
/**
*/
ControlObject GetTargetObject()
{
Vector vStart=GetPosition();
// strzelamy wektorem z kamery na odleglosc fMaxTargetDist
Vector vEnd=new Vector(GetForwardVector());
vEnd.Mul(-fMaxTriggerDist);
vEnd.Add(vStart);
// liczymy kolizje z obiektami
Collision stCollInfo = TraceObjectsExclude(vStart, vEnd, Target);
if(stCollInfo!=null)
{
// kolizja jest z jakims obiektem
//Log("Kolizja z " + stCollInfo.Obstacle.getClass().getName() + "\n");
return stCollInfo.Obstacle;
}
//Log(" po wszystkim " + vEnd + "\n");
// vEnd zawiera dociety po kolizji punkt
return null;
}
/** Metoda wczytujaca zapisane dane w Save gracza
*/
public void SGLoadChunk(FileChunk cParentFC)
{
FileChunk.Log("[CameraPlayer.SGLoadChunk]\n");
FileChunk cFC = GameObject.LoadChunk(cParentFC);
if (cFC.GetID() == ESGChunksChrome._CHK_CAMERA_PLAYER)
{
super.SGLoadChunk(cFC);
// paramtry odpowiedzialne za aproksymacje przejsc
fNewHeight = cFC.LoadFloat();
fCurHeight = cFC.LoadFloat();
fOldHeight = cFC.LoadFloat();
// paramtry odpowiedzialne za aproksymacje przejsc
fNewBackDistance = cFC.LoadFloat();
fCurBackDistance = cFC.LoadFloat();
fOldBackDistance = cFC.LoadFloat();
// Tryb pracy kamery
nCurrentMode = (byte)cFC.LoadInt();
nLastMode = (byte)cFC.LoadInt();
vCameraPos = cFC.LoadVector();
vCameraMove = cFC.LoadVector();
// Player, ktorego pokazuje kamera
Target = (Player)cFC.LoadObjectRef();
int nSprings = cFC.LoadInt();
if (nSprings < 0)
aCameraSpring = null;
else
{
aCameraSpring = new CameraShakeSpring[nSprings];
for (int i = 0; i < nSprings; i++)
aCameraSpring[i] = (CameraShakeSpring)cFC.LoadObject(aCameraSpring[i],this);
}
// ustawienia kamery gdy gracz kieruje pojazdem
m_fObservedSightVAngle = cFC.LoadFloat();
m_fOverObservedHeight = cFC.LoadFloat();
m_fOverObservedBack = cFC.LoadFloat();
m_fDestOverObservedHeight = cFC.LoadFloat();
m_fDestOverObservedBack = cFC.LoadFloat();
m_bChangeOverObservedParams = cFC.LoadBool();
// bron, znad ktorej patrzymy
// m_HeavyWeapon = (ICannonController)GameObject.cSG.LoadObjectRef(cFC);
if (cFC.LoadBool())
m_HeavyWeapon = null;
m_WeaponOwner = (MeshObject)cFC.LoadObjectRef();
m_fOverGunHeight = cFC.LoadFloat();
m_fOverGunBack = cFC.LoadFloat();
m_fOverGunHeightAim = cFC.LoadFloat();
m_fOverGunBackAim = cFC.LoadFloat();
m_fOverGunFOV = cFC.LoadFloat();
m_fOverGunAimFOV = cFC.LoadFloat();
m_fOldFOV = cFC.LoadFloat();
m_fOldOverObservedHeight = cFC.LoadFloat();
m_fOldOverObservedBack = cFC.LoadFloat();
m_vStartGunDir = cFC.LoadVector();
m_bUseGyro = cFC.LoadBool();
m_bAimingAllowed = cFC.LoadBool();
// Zoom kamery
m_fCurZoom = cFC.LoadFloat();
// Kat patrzenia gracza
fAimAngleY = cFC.LoadFloat();
// Kat patrzenia dla trybu smochodowego.
fDeltaYVehicle = cFC.LoadFloat();
fChangeTime = cFC.LoadFloat();
fLastSpringUpdate = cFC.LoadFloat();
// amplitudy do bujania w bobie
_fAmplX = cFC.LoadFloat();
_fAmplY = cFC.LoadFloat();
_fAmplGunX = cFC.LoadFloat();
_fAmplGunY = cFC.LoadFloat();
_fAmplAimX = cFC.LoadFloat();
_fAmplAimY = cFC.LoadFloat();
_fAmplAimGunX = cFC.LoadFloat();
_fAmplAimGunY = cFC.LoadFloat();
// czestotliwosc bujania w bobie
_fPeriod = cFC.LoadFloat();
m_vOldUp = cFC.LoadVector();
m_vOldForward = cFC.LoadVector();
m_vGunLookDir = cFC.LoadVector();
fLastVehicleYPos = cFC.LoadFloat();
fLastVehicleYSpeed = cFC.LoadFloat();
fLastVehicleYSpeedDiff = cFC.LoadFloat();
fLastCamPosYUpdateTime = cFC.LoadFloat();
fAmplitudeCoeff = cFC.LoadFloat();
ISaveGame savedObj = cFC.LoadObjectRef();
if (savedObj != null)
vehicleToUpdateSpring = (Vehicle) savedObj;
else
vehicleToUpdateSpring = null;
cCameraYSpring = (Spring) cFC.LoadObjectRef();
}
cFC.delete();
}
/** Metoda zapisujaca dane do Save gracza
*/
public void SGSaveChunk(FileChunk cFCParent)
{
FileChunk.Log("[CameraPlayer.SGSaveChunk]\n");
FileChunk cFC = NewChunk(ESGChunksChrome._CHK_CAMERA_PLAYER, cFCParent);
super.SGSaveChunk(cFC);
// paramtry odpowiedzialne za aproksymacje przejsc
cFC.SaveFloat(fNewHeight);
cFC.SaveFloat(fCurHeight);
cFC.SaveFloat(fOldHeight);
// paramtry odpowiedzialne za aproksymacje przejsc
cFC.SaveFloat(fNewBackDistance);
cFC.SaveFloat(fCurBackDistance);
cFC.SaveFloat(fOldBackDistance);
// tryb pracy kamery
cFC.SaveInt((int)nCurrentMode);
cFC.SaveInt((int)nLastMode);
cFC.SaveVector(vCameraPos);
cFC.SaveVector(vCameraMove);
// Player, ktorego pokazuje kamera
cFC.SaveObjectRef(Target);
if (aCameraSpring != null)
{
cFC.SaveInt(aCameraSpring.length);
for (int i = 0; i < aCameraSpring.length; i++)
cFC.SaveObject(aCameraSpring[i]);
}
else
cFC.SaveInt(-1);
// ustawienia kamery gdy gracz kieruje pojazdem
cFC.SaveFloat(m_fObservedSightVAngle);
cFC.SaveFloat(m_fOverObservedHeight);
cFC.SaveFloat(m_fOverObservedBack);
cFC.SaveFloat(m_fDestOverObservedHeight);
cFC.SaveFloat(m_fDestOverObservedBack);
cFC.SaveBool(m_bChangeOverObservedParams);
// bron, znad ktorej patrzymy
// GameObject.cSG.SaveObjectRef(cFC,(GameObject)m_HeavyWeapon);
cFC.SaveBool(m_HeavyWeapon == null);
cFC.SaveObjectRef(m_WeaponOwner);
cFC.SaveFloat(m_fOverGunHeight);
cFC.SaveFloat(m_fOverGunBack);
cFC.SaveFloat(m_fOverGunHeightAim);
cFC.SaveFloat(m_fOverGunBackAim);
cFC.SaveFloat(m_fOverGunFOV);
cFC.SaveFloat(m_fOverGunAimFOV);
cFC.SaveFloat(m_fOldFOV);
cFC.SaveFloat(m_fOldOverObservedHeight);
cFC.SaveFloat(m_fOldOverObservedBack);
cFC.SaveVector(m_vStartGunDir);
cFC.SaveBool(m_bUseGyro);
cFC.SaveBool(m_bAimingAllowed);
// Zoom kamery
cFC.SaveFloat(m_fCurZoom);
// Kat patrzenia gracza
cFC.SaveFloat(fAimAngleY);
// Kat patrzenia dla trybu smochodowego.
cFC.SaveFloat(fDeltaYVehicle);
//czasy
cFC.SaveFloat(fChangeTime);
cFC.SaveFloat(fLastSpringUpdate);
// amplitudy do bujania w bobie
cFC.SaveFloat(_fAmplX);
cFC.SaveFloat(_fAmplY);
cFC.SaveFloat(_fAmplGunX);
cFC.SaveFloat(_fAmplGunY);
cFC.SaveFloat(_fAmplAimX);
cFC.SaveFloat(_fAmplAimY);
cFC.SaveFloat(_fAmplAimGunX);
cFC.SaveFloat(_fAmplAimGunY);
// czestotliwosc bujania w bobie
cFC.SaveFloat(_fPeriod);
cFC.SaveVector(m_vOldUp);
cFC.SaveVector(m_vOldForward);
cFC.SaveVector(m_vGunLookDir);
// parametry do update kamery na sprezynie nad pojazdami
cFC.SaveFloat(fLastVehicleYPos);
cFC.SaveFloat(fLastVehicleYSpeed);
cFC.SaveFloat(fLastVehicleYSpeedDiff);
cFC.SaveFloat(fLastCamPosYUpdateTime);
cFC.SaveFloat(fAmplitudeCoeff);
cFC.SaveObjectRef(vehicleToUpdateSpring);
cFC.SaveObjectRef(cCameraYSpring);
cFC.delete();
}
public void SGUpdate()
{
FileChunk.Log("[CameraPlayer.SGUpdate]\n");
super.SGUpdate();
// ustawienie zoomu
SetZoom(m_fCurZoom);
// ustawienie odpowiedniego trybu kamery
byte nModeC = nCurrentMode;
byte nModeL = nLastMode;
nCurrentMode = -1;
SetMode(nModeC);
nLastMode = nModeL;
}
void UpdatePlayerSpeaker()
{
if (Target != null)
Target.UpdateSpeakerPos();
}
}
class Lissajouxer implements ISaveGame
{
// do ustawienia
float _fAmplX = 50;
float _fAmplY = 20;
// do ustawienia
float _fOffset = 90f;
float _fOffsetMul = 2f;
// do ustawienia
float fFadeInInterval = 1.f;
float fFadeOutInterval = 1.f;
float _fSinX = 0;
float _fSinY = 0;
float _fLastTime = 0;
float _fSinTime = 0;
float _fAmplFade;
float _fPeriod = 0.5f;
boolean bInterpAmpl = false;
float fInterpAmplStart = 0.f;
float fInterpAmplXSrc = 0.0f;
float fInterpAmplYSrc = 0.0f;
float fInterpAmplXDst = 0.0f;
float fInterpAmplYDst = 0.0f;
GameObject cGO = null;
Lissajouxer(GameObject cParent, float fAmplX, float fAmplY, float fOffset, float fOffsetMul, float fPeriod, float fAmplFade)
{
cGO = cParent;
Set(fAmplX, fAmplY, fOffset, fOffsetMul, fPeriod, fAmplFade);
}
void Set(float fAmplX, float fAmplY, float fOffset, float fOffsetMul, float fPeriod, float fAmplFade)
{
_fAmplX = fAmplX;
_fAmplY = fAmplY;
_fOffset = fOffset;
_fOffsetMul = fOffsetMul;
_fPeriod = fPeriod;
_fAmplFade = fAmplFade;
}
void SetAmpl(float fAmplX, float fAmplY, float fTime)
{
bInterpAmpl = true;
fInterpAmplXSrc = _fAmplX;
fInterpAmplYSrc = _fAmplY;
fInterpAmplXDst = fAmplX;
fInterpAmplYDst = fAmplY;
fInterpAmplStart = cGO.GetTime();
_fAmplFade = fTime;
}
void SetPeriod(float fPeriod)
{
_fPeriod = fPeriod;
}
float GetSinX() { return _fSinX; }
float GetSinY() { return _fSinY; }
void Update(float fNow)
{
float fDeltaTime = fNow - _fLastTime;
float fTime = _fSinTime;
// interpolujemy amplitude
if(bInterpAmpl)
{
float fDelta = (cGO.GetTime() - fInterpAmplStart);
if(fDelta < _fAmplFade)
{
fDelta /= _fAmplFade;
_fAmplX = fInterpAmplXSrc + (fInterpAmplXDst - fInterpAmplXSrc)*fDelta;
_fAmplY = fInterpAmplYSrc + (fInterpAmplYDst - fInterpAmplYSrc)*fDelta;
}
else
{
_fAmplX = fInterpAmplXDst;
_fAmplY = fInterpAmplYDst;
bInterpAmpl = false;
}
}
// interp. end
float fFracX = 360.f*fTime/_fPeriod + _fOffset;
_fSinX = _fAmplX * (float)java.lang.Math.sin((float)java.lang.Math.PI * fFracX/180f);
float fFracY = 360.f*fTime/_fPeriod;
_fSinY = _fAmplY * (float)java.lang.Math.sin(_fOffsetMul * (float)java.lang.Math.PI * fFracY/180f);
_fSinTime += fDeltaTime;
// zapisujemy stary czas
_fLastTime = fNow;
}
public void SGSaveChunk(FileChunk cFC)
{
_fLastTime = cFC.LoadFloat();
_fSinTime = cFC.LoadFloat();
}
public void SGLoadChunk(FileChunk cFC)
{
cFC.SaveFloat(_fLastTime);
cFC.SaveFloat(_fSinTime);
}
public void SGUpdate() {}
}
/** Sprezyna z funkcjami trzesienia kamera
*/
class CameraShakeSpring extends Spring
{
/** Wspolczynnik wplywu sprezyny na pozycje */
public float m_fPosMult = 1;
/** Wspolczynnik wplywu sprezyny na kat */
public float m_fDirMult = 1;
public CameraShakeSpring()
{
}
public CameraShakeSpring(float fPosMult, float fDirMult)
{
super();
m_fPosMult = fPosMult;
m_fDirMult = fDirMult;
}
public void Update(float fDeltaTime)
{
if (IsInduced())
Calculate(fDeltaTime);
}
private Vector m_vGSPPos = new Vector();
public Vector GetShakePos()
{
m_vGSPPos.Set(GetPosition());
m_vGSPPos.Mul(m_fPosMult);
return m_vGSPPos;
}
private Vector m_vGSAAng = new Vector();
public Vector GetShakeAngle()
{
m_vGSAAng.Set(GetPosition());
m_vGSAAng.Mul(m_fDirMult);
return m_vGSAAng;
}
public void SGLoadChunk(FileChunk cParentFC)
{
super.SGLoadChunk(cParentFC);
FileChunk.Log("[CameraShakeSpring.SGLoadChunk]\n");
FileChunk cFC = GameObject.LoadChunk(cParentFC);
if (cFC.GetID() == ESGChunksChrome._CHK_CAMERA_SHAKE_SPRING)
{
// Wspolczynnik wplywu sprezyny na pozycje
m_fPosMult = cFC.LoadFloat();
// Wspolczynnik wplywu sprezyny na kat
m_fDirMult = cFC.LoadFloat();
}
m_vGSPPos.Set(Vector.Zero);
m_vGSAAng.Set(Vector.Zero);
FileChunk.Log("[SeatInfo.SGLoadChunk] - END\n");
cFC.delete();
}
/** Metoda zapisujaca dane do Save gracza
*/
public void SGSaveChunk(FileChunk cFCParent)
{
super.SGSaveChunk(cFCParent);
FileChunk.Log("[CameraShakeSpring.SGSaveChunk]\n");
FileChunk cFC = GameObject.NewChunk(ESGChunksChrome._CHK_CAMERA_SHAKE_SPRING, cFCParent);
// Wspolczynnik wplywu sprezyny na pozycje
cFC.SaveFloat(m_fPosMult);
// Wspolczynnik wplywu sprezyny na kat
cFC.SaveFloat(m_fDirMult);
cFC.delete();
}
}
/** CameraShakeSpring do bumpa
*/
class CameraShakeSpringBump extends CameraShakeSpring
{
/** aktualne wychylenie sprezyny w Y podczas tapniecia */
public float m_fBumpLastPosY = 0.0f;
public CameraShakeSpringBump()
{
super();
// TYLKO SG!
}
public CameraShakeSpringBump(float fPosMult, float fDirMult)
{
super(fPosMult, fDirMult);
}
public void Update(float fDeltaTime)
{
super.Update(fDeltaTime);
Vector vPos = GetPosition();
if ( m_fBumpLastPosY < 0.0f && vPos.fY >= 0.0f )
{
// zatrzymaj sprezyne
SetPosition(Vector.Zero);
SetVelocity(Vector.Zero);
}
m_fBumpLastPosY = vPos.fY;
}
public void SGLoadChunk(FileChunk cParentFC)
{
FileChunk.Log("[CameraShakeSpring.SGLoadChunk]\n");
FileChunk cFC = GameObject.LoadChunk(cParentFC);
if (cFC.GetID() == ESGChunksChrome._CHK_CAMERA_SHAKE_SPRING)
{
super.SGLoadChunk(cFC);
// Wspolczynnik wplywu sprezyny na pozycje
m_fBumpLastPosY = cFC.LoadFloat();
}
FileChunk.Log("[SeatInfo.SGLoadChunk] - END\n");
cFC.delete();
}
/** Metoda zapisujaca dane do Save gracza
*/
public void SGSaveChunk(FileChunk cFCParent)
{
FileChunk.Log("[CameraShakeSpring.SGSaveChunk]\n");
FileChunk cFC = GameObject.NewChunk(ESGChunksChrome._CHK_CAMERA_SHAKE_SPRING, cFCParent);
super.SGSaveChunk(cFC);
// Wspolczynnik wplywu sprezyny na pozycje
cFC.SaveFloat(m_fBumpLastPosY);
cFC.delete();
}
}