2 * Copyright (C) 2003 Robert Kooima
4 * NEVERBALL is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
17 #include "solid_vary.h"
21 /*---------------------------------------------------------------------------*/
23 int sol_load_vary(struct s_vary *fp, const struct s_base *base)
27 memset(fp, 0, sizeof (*fp));
33 fp->pv = calloc(fp->base->pc, sizeof (*fp->pv));
34 fp->pc = fp->base->pc;
36 for (i = 0; i < fp->base->pc; i++)
38 struct v_path *pp = fp->pv + i;
39 struct b_path *pq = fp->base->pv + i;
48 fp->bv = calloc(fp->base->bc, sizeof (*fp->bv));
49 fp->bc = fp->base->bc;
51 for (i = 0; i < fp->base->bc; i++)
53 struct v_body *bp = fp->bv + i;
54 struct b_body *bq = fp->base->bv + i;
63 fp->hv = calloc(fp->base->hc, sizeof (*fp->hv));
64 fp->hc = fp->base->hc;
66 for (i = 0; i < fp->base->hc; i++)
68 struct v_item *hp = fp->hv + i;
69 struct b_item *hq = fp->base->hv + i;
80 fp->xv = calloc(fp->base->xc, sizeof (*fp->xv));
81 fp->xc = fp->base->xc;
83 for (i = 0; i < fp->base->xc; i++)
85 struct v_swch *xp = fp->xv + i;
86 struct b_swch *xq = fp->base->xv + i;
97 fp->uv = calloc(fp->base->uc, sizeof (*fp->uv));
98 fp->uc = fp->base->uc;
100 for (i = 0; i < fp->base->uc; i++)
102 struct v_ball *up = fp->uv + i;
103 struct b_ball *uq = fp->base->uv + i;
109 up->E[0][0] = up->e[0][0] = 1.0f;
110 up->E[0][1] = up->e[0][1] = 0.0f;
111 up->E[0][2] = up->e[0][2] = 0.0f;
113 up->E[1][0] = up->e[1][0] = 0.0f;
114 up->E[1][1] = up->e[1][1] = 1.0f;
115 up->E[1][2] = up->e[1][2] = 0.0f;
117 up->E[2][0] = up->e[2][0] = 0.0f;
118 up->E[2][1] = up->e[2][1] = 0.0f;
119 up->E[2][2] = up->e[2][2] = 1.0f;
126 void sol_free_vary(struct s_vary *fp)
128 if (fp->pv) free(fp->pv);
129 if (fp->bv) free(fp->bv);
130 if (fp->hv) free(fp->hv);
131 if (fp->xv) free(fp->xv);
132 if (fp->uv) free(fp->uv);
134 memset(fp, 0, sizeof (*fp));
137 /*---------------------------------------------------------------------------*/
142 int sol_lerp_cmd(struct s_lerp *fp, struct cmd_state *cs, const union cmd *cmd)
144 struct l_ball (*uv)[2];
152 if ((uv = realloc(fp->uv, sizeof (*uv) * (fp->uc + 1))))
159 /* Sync the main structure. */
161 if ((up = realloc(fp->vary->uv, sizeof (*up) * fp->uc)))
164 fp->vary->uc = fp->uc;
166 cs->curr_ball = fp->uc - 1;
173 fp->bv[cmd->bodypath.bi][CURR].pi = cmd->bodypath.pi;
177 fp->bv[cmd->bodytime.bi][CURR].t = cmd->bodytime.t;
180 case CMD_BALL_RADIUS:
181 fp->uv[cs->curr_ball][CURR].r = cmd->ballradius.r;
184 case CMD_CLEAR_BALLS:
194 case CMD_BALL_POSITION:
195 up = &fp->uv[cs->curr_ball][CURR];
196 v_cpy(up->p, cmd->ballpos.p);
200 up = &fp->uv[cs->curr_ball][CURR];
201 v_cpy(up->e[0], cmd->ballbasis.e[0]);
202 v_cpy(up->e[1], cmd->ballbasis.e[1]);
203 v_crs(up->e[2], up->e[0], up->e[1]);
206 case CMD_BALL_PEND_BASIS:
207 up = &fp->uv[cs->curr_ball][CURR];
208 v_cpy(up->E[0], cmd->ballpendbasis.E[0]);
209 v_cpy(up->E[1], cmd->ballpendbasis.E[1]);
210 v_crs(up->E[2], up->E[0], up->E[1]);
213 case CMD_STEP_SIMULATION:
215 * Simulate body motion.
217 * This is done on the client side due to replay file size
218 * concerns and isn't done as part of CMD_END_OF_UPDATE to
219 * match the server state as closely as possible. Body time
220 * is still synchronized with the server on a semi-regular
221 * basis and path indices are handled through CMD_BODY_PATH,
222 * thus this code doesn't need to be as sophisticated as
226 for (i = 0; i < fp->bc; i++)
228 struct l_body *bp = &fp->bv[i][CURR];
229 struct v_path *pp = &fp->vary->pv[bp->pi];
231 if (bp->pi >= 0 && pp->f)
232 bp->t += cmd->stepsim.dt;
243 void sol_lerp_copy(struct s_lerp *fp)
247 for (i = 0; i < fp->bc; i++)
248 fp->bv[i][PREV] = fp->bv[i][CURR];
250 for (i = 0; i < fp->uc; i++)
251 fp->uv[i][PREV] = fp->uv[i][CURR];
254 void sol_lerp_apply(struct s_lerp *fp, float a)
258 for (i = 0; i < fp->bc; i++)
260 if (fp->bv[i][PREV].pi == fp->bv[i][CURR].pi)
261 fp->vary->bv[i].t = (fp->bv[i][PREV].t * (1.0f - a) +
262 fp->bv[i][CURR].t * a);
264 fp->vary->bv[i].t = fp->bv[i][CURR].t * a;
266 fp->vary->bv[i].pi = fp->bv[i][CURR].pi;
269 for (i = 0; i < fp->uc; i++)
271 e_lerp(fp->vary->uv[i].e, fp->uv[i][PREV].e, fp->uv[i][CURR].e, a);
272 v_lerp(fp->vary->uv[i].p, fp->uv[i][PREV].p, fp->uv[i][CURR].p, a);
273 e_lerp(fp->vary->uv[i].E, fp->uv[i][PREV].E, fp->uv[i][CURR].E, a);
275 fp->vary->uv[i].r = (fp->uv[i][PREV].r * (1.0f - a) +
276 fp->uv[i][CURR].r * a);
280 int sol_load_lerp(struct s_lerp *fp, struct s_vary *vary)
288 fp->bv = calloc(fp->vary->bc, sizeof (*fp->bv));
289 fp->bc = fp->vary->bc;
291 for (i = 0; i < fp->vary->bc; i++)
292 fp->bv[i][CURR].pi = fp->vary->bv[i].pi;
297 fp->uv = calloc(fp->vary->uc, sizeof (*fp->uv));
298 fp->uc = fp->vary->uc;
300 for (i = 0; i < fp->vary->uc; i++)
302 e_cpy(fp->uv[i][CURR].e, fp->vary->uv[i].e);
303 v_cpy(fp->uv[i][CURR].p, fp->vary->uv[i].p);
304 e_cpy(fp->uv[i][CURR].E, fp->vary->uv[i].E);
306 fp->uv[i][CURR].r = fp->vary->uv[i].r;
315 void sol_free_lerp(struct s_lerp *fp)
317 if (fp->bv) free(fp->bv);
318 if (fp->uv) free(fp->uv);
320 memset(fp, 0, sizeof (*fp));
323 /*---------------------------------------------------------------------------*/