-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathCIntegralRotationDesc.cpp
128 lines (93 loc) · 3.3 KB
/
CIntegralRotationDesc.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// CIntegralRotationDesc.cpp
//
// CIntegralRotationDesc class
// Copyright (c) 2016 by Kronosaur Productions, LLC. All Rights Reserved.
#include "PreComp.h"
const Metric MANEUVER_MASS_FACTOR = 1.0;
const Metric MAX_INERTIA_RATIO = 9.0;
CIntegralRotationDesc::SFacingsData CIntegralRotationDesc::m_FacingsData[360 + 1];
CIntegralRotationDesc::CIntegralRotationDesc (void) :
m_iCount(20),
m_iMaxRotationRate(0),
m_iRotationAccel(0),
m_iRotationAccelStop(0)
// CIntegralRotationDesc constructor
{
}
int CIntegralRotationDesc::CalcFinalRotationFrame (int iRotationFrame, int iRotationSpeed) const
// CalcFinalRotationFrame
//
// Try to figure out what our final rotation frame would be if we stopped
// thrusting and turned on inertia only.
{
while (iRotationSpeed > m_iRotationAccelStop || iRotationSpeed < -m_iRotationAccelStop)
{
if (iRotationSpeed > 0)
iRotationSpeed = Max(0, iRotationSpeed - m_iRotationAccelStop);
else
iRotationSpeed = Min(0, iRotationSpeed + m_iRotationAccelStop);
if (iRotationSpeed != 0)
{
int iFrameMax = m_iCount * ROTATION_FRACTION;
iRotationFrame = (iRotationFrame + iRotationSpeed) % iFrameMax;
if (iRotationFrame < 0)
iRotationFrame += iFrameMax;
}
}
return iRotationFrame;
}
int CIntegralRotationDesc::GetManeuverDelay (void) const
// GetManeuverDelay
//
// For compatibility we convert from our internal units to old style
// maneuverability (ticks per rotation angle)
{
return (m_iMaxRotationRate > 0 ? (int)(ROTATION_FRACTION / m_iMaxRotationRate) : 0);
}
Metric CIntegralRotationDesc::GetMaxRotationSpeedDegrees (void) const
// GetMaxRotationSpeedDegrees
//
// Returns the max speed in degrees per tick.
{
if (m_iCount == 0)
return 0.0;
return 360.0 * m_iMaxRotationRate / (ROTATION_FRACTION * m_iCount);
}
void CIntegralRotationDesc::Init (int iFrameCount, Metric rMaxRotation, Metric rAccel, Metric rAccelStop)
// Init
//
// Initialize from constants
{
m_iCount = iFrameCount;
m_iMaxRotationRate = Max(1, mathRound(ROTATION_FRACTION * rMaxRotation * m_iCount / 360.0));
m_iRotationAccel = Max(1, mathRound(ROTATION_FRACTION * rAccel * m_iCount / 360.0));
m_iRotationAccelStop = Max(1, mathRound(ROTATION_FRACTION * rAccelStop * m_iCount / 360.0));
InitFacingsData(m_iCount);
}
bool CIntegralRotationDesc::InitFacingsData (int iCount)
// InitFacingsData
//
// Initializes facings data. Return FALSE if iCount is invalid.
{
int i;
if (iCount <= 0 || iCount > 360)
return false;
if (m_FacingsData[iCount].bInitialized)
return true;
m_FacingsData[iCount].FrameIndexToAngle.InsertEmpty(iCount);
Metric rFrameAngle = 360.0 / iCount;
for (i = 0; i < iCount; i++)
m_FacingsData[iCount].FrameIndexToAngle[i] = AngleMod(mathRound(90.0 - i * rFrameAngle));
m_FacingsData[iCount].AngleToFrameIndex.InsertEmpty(360);
for (i = 0; i < 360; i++)
m_FacingsData[iCount].AngleToFrameIndex[i] = mathRound(AngleMod(90 - i) * iCount / 360.0) % iCount;
m_FacingsData[iCount].bInitialized = true;
return true;
}
void CIntegralRotationDesc::InitFromDesc (const CRotationDesc &Desc)
// InitFromDesc
//
// Initialize from a descriptor (which uses double precision)
{
Init(Desc.GetFrameCount(), Desc.GetMaxRotationPerTick(), Desc.GetRotationAccelPerTick(), Desc.GetRotationAccelStopPerTick());
}