OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
spline.h
1/*
2===========================================================================
3Copyright (C) 2015 the OpenMoHAA team
4
5This file is part of OpenMoHAA source code.
6
7OpenMoHAA source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OpenMoHAA source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OpenMoHAA source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20===========================================================================
21*/
22
23// spline.h: Spline paths.
24//
25
26#pragma once
27
28#include "g_local.h"
29#include <class.h>
30
31template<unsigned int cGrids, unsigned int cPoints>
32class cSpline : public Class
33{
34public:
35 int m_iPoints;
36 float m_vPoints[cPoints][cGrids];
37 int m_iPointFlags[cPoints];
38
39 cSpline();
40
41 void Reset(void);
42 int Add(float *fAdd, int flags);
43 void Modify(int, float *, int);
44 void UniformAdd(float *pos);
45 void Remove(class cSpline<cGrids, cPoints> *, int);
46 void RemoveRange(int, int);
47 int Right(float x);
48 float *Get(float x, int *flags);
49 float *GetByNode(float x, int *flags);
50 int Append(cSpline<cGrids, cPoints> *pNew);
51
52 void Archive(Archiver& arc);
53};
54
55template<unsigned int cGrids, unsigned int cPoints>
56cSpline<cGrids, cPoints>::cSpline()
57{
58 m_iPoints = 0;
59}
60
61template<unsigned int cGrids, unsigned int cPoints>
62void cSpline<cGrids, cPoints>::Archive(Archiver& arc)
63{
64 arc.ArchiveInteger(&m_iPoints);
65
66 for (int i = 0; i < cPoints; i++) {
67 for (int j = 0; j < cGrids; j++) {
68 arc.ArchiveFloat(&m_vPoints[i][j]);
69 }
70
71 arc.ArchiveInteger(&m_iPointFlags[i]);
72 }
73}
74
75template<unsigned int cGrids, unsigned int cPoints>
76void cSpline<cGrids, cPoints>::Reset(void)
77{
78 m_iPoints = 0;
79}
80
81template<unsigned int cGrids, unsigned int cPoints>
82int cSpline<cGrids, cPoints>::Add(float *fAdd, int flags)
83{
84 int i;
85 int ii;
86 int insertIndex;
87
88 if (m_iPoints + 1 > cPoints) {
89 return -1;
90 }
91
92 insertIndex = Right(*fAdd);
93
94 for (i = m_iPoints; i > insertIndex; i--) {
95 for (ii = 0; ii < cGrids; ii++) {
96 m_vPoints[i][ii] = m_vPoints[i - 1][ii];
97 }
98
99 m_iPointFlags[i] = m_iPointFlags[i - 1];
100 }
101
102 for (i = 0; i < cGrids; i++) {
103 m_vPoints[insertIndex][i] = fAdd[i];
104 }
105
106 m_iPointFlags[insertIndex] = flags;
107 m_iPoints++;
108
109 return insertIndex;
110}
111
112template<unsigned int cGrids, unsigned int cPoints>
113void cSpline<cGrids, cPoints>::UniformAdd(float *pos)
114{
115 int i;
116 int ii;
117
118 for (i = 0; i < m_iPoints; i++) {
119 for (ii = 0; ii < cGrids; ii++) {
120 m_vPoints[i][ii] += pos[ii];
121 }
122 }
123}
124
125template<unsigned int cGrids, unsigned int cPoints>
126int cSpline<cGrids, cPoints>::Right(float x)
127{
128 int i;
129
130 for (i = 0; i < m_iPoints; i++) {
131 if (m_vPoints[i][0] > x) {
132 break;
133 }
134 }
135
136 return i;
137}
138
139template<unsigned int cGrids, unsigned int cPoints>
140float *cSpline<cGrids, cPoints>::Get(float x, int *flags)
141{
142 if (!m_iPoints) {
143 return NULL;
144 }
145
146 int rp;
147 int i;
148 static float r[cGrids];
149 double delta[cGrids];
150
151 rp = Right(x);
152
153 if (rp) {
154 if (rp == m_iPoints) {
155 if (flags) {
156 *flags = m_iPointFlags[rp - 1];
157 }
158
159 for (i = 0; i < cGrids; i++) {
160 r[i] = m_vPoints[rp - 1][i];
161 }
162 } else {
163 if (flags) {
164 *flags = m_iPointFlags[rp - 1];
165 }
166
167 for (i = 0; i < cGrids; i++) {
168 delta[i] = m_vPoints[rp][i] - m_vPoints[rp - 1][i];
169 }
170
171 for (i = 0; i < cGrids; i++) {
172 r[i] = (x - m_vPoints[rp - 1][0]) / delta[0] * delta[i] + m_vPoints[rp - 1][i];
173 }
174 }
175 } else {
176 if (flags) {
177 *flags = m_iPointFlags[0];
178 }
179
180 for (i = 0; i < cGrids; i++) {
181 r[i] = m_vPoints[0][i];
182 }
183 }
184
185 return r;
186}
187
188template<unsigned int cGrids, unsigned int cPoints>
189float *cSpline<cGrids, cPoints>::GetByNode(float x, int *flags)
190{
191 if (!m_iPoints) {
192 return NULL;
193 }
194
195 int rp;
196 int i;
197 static float r[cGrids];
198 double delta[cGrids];
199
200 rp = (int)(floor(x) + 1.0);
201
202 if (rp <= 0) {
203 if (flags) {
204 *flags = m_iPointFlags[0];
205 }
206
207 for (i = 0; i < cGrids; i++) {
208 r[i] = m_vPoints[0][i];
209 }
210 } else if (rp < m_iPoints) {
211 if (flags) {
212 *flags = m_iPointFlags[rp - 1];
213 }
214
215 for (i = 0; i < cGrids; i++) {
216 delta[i] = m_vPoints[rp][i] - m_vPoints[rp - 1][i];
217 }
218
219 for (i = 0; i < cGrids; i++) {
220 r[i] = (x - (rp - 1)) * delta[i] + m_vPoints[rp - 1][i];
221 }
222 } else {
223 if (flags) {
224 *flags = m_iPointFlags[m_iPoints - 1];
225 }
226
227 for (i = 0; i < cGrids; i++) {
228 r[i] = m_vPoints[m_iPoints - 1][i];
229 }
230 }
231
232 return r;
233}
234
235template<unsigned int cGrids, unsigned int cPoints>
236int cSpline<cGrids, cPoints>::Append(cSpline<cGrids, cPoints> *pNew)
237{
238 float *i_fTmp;
239 float o_fTmp[4];
240 float fIndexAdd;
241 int i;
242 int ii;
243 int iFlags = 0;
244
245 if (!pNew || pNew->m_iPoints == 0) {
246 return -1;
247 }
248
249 if (m_iPoints) {
250 int points;
251
252 points = m_iPoints;
253 fIndexAdd = *GetByNode(m_iPoints, NULL);
254
255 for (i = 0; i < pNew->m_iPoints; i++) {
256 i_fTmp = pNew->GetByNode(i, &iFlags);
257
258 for (ii = 0; ii < cGrids; ii++) {
259 o_fTmp[ii] = i_fTmp[ii];
260 }
261
262 o_fTmp[0] += fIndexAdd;
263 Add(o_fTmp, iFlags);
264 }
265
266 return points;
267 } else {
268 for (i = 0; i < pNew->m_iPoints; i++) {
269 i_fTmp = pNew->GetByNode(i, &iFlags);
270
271 for (ii = 0; ii < cGrids; ii++) {
272 o_fTmp[ii] = i_fTmp[ii];
273 }
274
275 Add(o_fTmp, iFlags);
276 }
277
278 return 0;
279 }
280}
Definition archive.h:86
Definition spline.h:33