|
|
1.1 root 1:
2: #include "client.h"
3:
4:
5: /*
6: ===================
7: CL_CheckPredictionError
8: ===================
9: */
10: void CL_CheckPredictionError (void)
11: {
12: int frame;
13: int delta[3];
14: int i;
15: int len;
16:
17: if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
18: return;
19:
20: // calculate the last usercmd_t we sent that the server has processed
21: frame = cls.netchan.incoming_acknowledged;
22: frame &= (CMD_BACKUP-1);
23:
24: // compare what the server returned with what we had predicted it to be
25: VectorSubtract (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame], delta);
26:
27: // save the prediction error for interpolation
28: len = abs(delta[0]) + abs(delta[1]) + abs(delta[2]);
29: if (len > 640) // 80 world units
30: { // a teleport or something
31: VectorClear (cl.prediction_error);
32: }
33: else
34: {
35: if (cl_showmiss->value && (delta[0] || delta[1] || delta[2]) )
36: Com_Printf ("prediction miss on %i: %i\n", cl.frame.serverframe,
37: delta[0] + delta[1] + delta[2]);
38:
39: VectorCopy (cl.frame.playerstate.pmove.origin, cl.predicted_origins[frame]);
40:
41: // save for error itnerpolation
42: for (i=0 ; i<3 ; i++)
43: cl.prediction_error[i] = delta[i]*0.125;
44: }
45: }
46:
47:
48: /*
49: ====================
50: CL_ClipMoveToEntities
51:
52: ====================
53: */
54: void CL_ClipMoveToEntities ( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, trace_t *tr )
55: {
56: int i, x, zd, zu;
57: trace_t trace;
58: int headnode;
59: float *angles;
60: entity_state_t *ent;
61: int num;
62: cmodel_t *cmodel;
63: vec3_t bmins, bmaxs;
64:
65: for (i=0 ; i<cl.frame.num_entities ; i++)
66: {
67: num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
68: ent = &cl_parse_entities[num];
69:
70: if (!ent->solid)
71: continue;
72:
73: if (ent->number == cl.playernum+1)
74: continue;
75:
76: if (ent->solid == 31)
77: { // special value for bmodel
78: cmodel = cl.model_clip[ent->modelindex];
79: if (!cmodel)
80: continue;
81: headnode = cmodel->headnode;
82: angles = ent->angles;
83: }
84: else
85: { // encoded bbox
86: x = 8*(ent->solid & 31);
87: zd = 8*((ent->solid>>5) & 31);
88: zu = 8*((ent->solid>>10) & 63) - 32;
89:
90: bmins[0] = bmins[1] = -x;
91: bmaxs[0] = bmaxs[1] = x;
92: bmins[2] = -zd;
93: bmaxs[2] = zu;
94:
95: headnode = CM_HeadnodeForBox (bmins, bmaxs);
96: angles = vec3_origin; // boxes don't rotate
97: }
98:
99: if (tr->allsolid)
100: return;
101:
102: trace = CM_TransformedBoxTrace (start, end,
103: mins, maxs, headnode, MASK_PLAYERSOLID,
104: ent->origin, angles);
105:
106: if (trace.allsolid || trace.startsolid ||
107: trace.fraction < tr->fraction)
108: {
109: trace.ent = (struct edict_s *)ent;
110: if (tr->startsolid)
111: {
112: *tr = trace;
113: tr->startsolid = true;
114: }
115: else
116: *tr = trace;
117: }
118: else if (trace.startsolid)
119: tr->startsolid = true;
120: }
121: }
122:
123:
124: /*
125: ================
126: CL_PMTrace
127: ================
128: */
129: trace_t CL_PMTrace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
130: {
131: trace_t t;
132:
133: // check against world
134: t = CM_BoxTrace (start, end, mins, maxs, 0, MASK_PLAYERSOLID);
135: if (t.fraction < 1.0)
136: t.ent = (struct edict_s *)1;
137:
138: // check all other solid models
139: CL_ClipMoveToEntities (start, mins, maxs, end, &t);
140:
141: return t;
142: }
143:
144: int CL_PMpointcontents (vec3_t point)
145: {
146: int i;
147: entity_state_t *ent;
148: int num;
149: cmodel_t *cmodel;
150: int contents;
151:
152: contents = CM_PointContents (point, 0);
153:
154: for (i=0 ; i<cl.frame.num_entities ; i++)
155: {
156: num = (cl.frame.parse_entities + i)&(MAX_PARSE_ENTITIES-1);
157: ent = &cl_parse_entities[num];
158:
159: if (ent->solid != 31) // special value for bmodel
160: continue;
161:
162: cmodel = cl.model_clip[ent->modelindex];
163: if (!cmodel)
164: continue;
165:
166: contents |= CM_TransformedPointContents (point, cmodel->headnode, ent->origin, ent->angles);
167: }
168:
169: return contents;
170: }
171:
172:
173: /*
174: =================
175: CL_PredictMovement
176:
177: Sets cl.predicted_origin and cl.predicted_angles
178: =================
179: */
180: void CL_PredictMovement (void)
181: {
182: int ack, current;
183: int frame;
184: int oldframe;
185: usercmd_t *cmd;
186: pmove_t pm;
187: int i;
188: int step;
189: int oldz;
190:
191: if (cls.state != ca_active)
192: return;
193:
194: if (cl_paused->value)
195: return;
196:
197: if (!cl_predict->value || (cl.frame.playerstate.pmove.pm_flags & PMF_NO_PREDICTION))
198: { // just set angles
199: for (i=0 ; i<3 ; i++)
200: {
201: cl.predicted_angles[i] = cl.viewangles[i] + SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[i]);
202: }
203: return;
204: }
205:
206: ack = cls.netchan.incoming_acknowledged;
207: current = cls.netchan.outgoing_sequence;
208:
209: // if we are too far out of date, just freeze
210: if (current - ack >= CMD_BACKUP)
211: {
212: if (cl_showmiss->value)
213: Com_Printf ("exceeded CMD_BACKUP\n");
214: return;
215: }
216:
217: // copy current state to pmove
218: memset (&pm, 0, sizeof(pm));
219: pm.trace = CL_PMTrace;
220: pm.pointcontents = CL_PMpointcontents;
221:
222: pm.s = cl.frame.playerstate.pmove;
223:
224: // SCR_DebugGraph (current - ack - 1, 0);
225:
226: frame = 0;
227:
228: // run frames
229: while (++ack < current)
230: {
231: frame = ack & (CMD_BACKUP-1);
232: cmd = &cl.cmds[frame];
233:
234: pm.cmd = *cmd;
235: Pmove (&pm);
236:
237: // save for debug checking
238: VectorCopy (pm.s.origin, cl.predicted_origins[frame]);
239: }
240:
241: oldframe = (ack-2) & (CMD_BACKUP-1);
242: oldz = cl.predicted_origins[oldframe][2];
243: step = pm.s.origin[2] - oldz;
244: if (step > 63 && step < 160 && (pm.s.pm_flags & PMF_ON_GROUND) )
245: {
246: cl.predicted_step = step * 0.125;
247: cl.predicted_step_time = cls.realtime - cls.frametime * 500;
248: }
249:
250:
251: // copy results out for rendering
252: cl.predicted_origin[0] = pm.s.origin[0]*0.125;
253: cl.predicted_origin[1] = pm.s.origin[1]*0.125;
254: cl.predicted_origin[2] = pm.s.origin[2]*0.125;
255:
256: VectorCopy (pm.viewangles, cl.predicted_angles);
257: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.