Optimization for quaternion structure: Stuffed orientation in shorts and removed figure out segnum by position - saving 10 bytes for each positional update in Multiplayer; Also removed render_type from pdata to save yet another byte
This commit is contained in:
parent
87e9757577
commit
3d10827ca3
|
@ -4,6 +4,7 @@ D2X-Rebirth Changelog
|
|||
--------
|
||||
main/collide.c: Fit player/player collisions to not take damage from bump while remote player has possibly not aligned to the collision, yet; Added FORCE_DAMAGE_THRESHOLD for minimum force damage to receive from object bumps to not simply take damage from touching objects
|
||||
main/net_udp.c: Fixed one more copy/paste issue causeing positional updates relayed to possibly disconnected players
|
||||
include/vecmat.h, main/gameseg.c, main/multi.h, main/net_udp.c, main/net_udp.h, main/object.h, maths/vecmat.c: Optimization for quaternion structure: Stuffed orientation in shorts and removed figure out segnum by position - saving 10 bytes for each positional update in Multiplayer; Also removed render_type from pdata to save yet another byte
|
||||
|
||||
20120525
|
||||
--------
|
||||
|
|
|
@ -67,7 +67,7 @@ __pack__ vms_matrix;
|
|||
// Quaternion structure
|
||||
typedef struct vms_quaternion
|
||||
{
|
||||
fix w, x, y, z;
|
||||
signed short w, x, y, z;
|
||||
} __pack__ vms_quaternion;
|
||||
|
||||
|
||||
|
|
|
@ -1178,14 +1178,12 @@ void create_quaternionpos(quaternionpos * qpp, object * objp, int swap_bytes)
|
|||
qpp->vel = objp->mtype.phys_info.velocity;
|
||||
qpp->rotvel = objp->mtype.phys_info.rotvel;
|
||||
|
||||
qpp->segnum = objp->segnum;
|
||||
|
||||
if (swap_bytes)
|
||||
{
|
||||
qpp->orient.w = INTEL_INT(qpp->orient.w);
|
||||
qpp->orient.x = INTEL_INT(qpp->orient.x);
|
||||
qpp->orient.y = INTEL_INT(qpp->orient.y);
|
||||
qpp->orient.z = INTEL_INT(qpp->orient.z);
|
||||
qpp->orient.w = INTEL_SHORT(qpp->orient.w);
|
||||
qpp->orient.x = INTEL_SHORT(qpp->orient.x);
|
||||
qpp->orient.y = INTEL_SHORT(qpp->orient.y);
|
||||
qpp->orient.z = INTEL_SHORT(qpp->orient.z);
|
||||
qpp->pos.x = INTEL_INT(qpp->pos.x);
|
||||
qpp->pos.y = INTEL_INT(qpp->pos.y);
|
||||
qpp->pos.z = INTEL_INT(qpp->pos.z);
|
||||
|
@ -1195,20 +1193,17 @@ void create_quaternionpos(quaternionpos * qpp, object * objp, int swap_bytes)
|
|||
qpp->rotvel.x = INTEL_INT(qpp->rotvel.x);
|
||||
qpp->rotvel.y = INTEL_INT(qpp->rotvel.y);
|
||||
qpp->rotvel.z = INTEL_INT(qpp->rotvel.z);
|
||||
qpp->segnum = INTEL_INT(qpp->segnum);
|
||||
}
|
||||
}
|
||||
|
||||
void extract_quaternionpos(object *objp, quaternionpos *qpp, int swap_bytes)
|
||||
{
|
||||
int segnum;
|
||||
|
||||
if (swap_bytes)
|
||||
{
|
||||
qpp->orient.w = INTEL_INT(qpp->orient.w);
|
||||
qpp->orient.x = INTEL_INT(qpp->orient.x);
|
||||
qpp->orient.y = INTEL_INT(qpp->orient.y);
|
||||
qpp->orient.z = INTEL_INT(qpp->orient.z);
|
||||
qpp->orient.w = INTEL_SHORT(qpp->orient.w);
|
||||
qpp->orient.x = INTEL_SHORT(qpp->orient.x);
|
||||
qpp->orient.y = INTEL_SHORT(qpp->orient.y);
|
||||
qpp->orient.z = INTEL_SHORT(qpp->orient.z);
|
||||
qpp->pos.x = INTEL_INT(qpp->pos.x);
|
||||
qpp->pos.y = INTEL_INT(qpp->pos.y);
|
||||
qpp->pos.z = INTEL_INT(qpp->pos.z);
|
||||
|
@ -1218,7 +1213,6 @@ void extract_quaternionpos(object *objp, quaternionpos *qpp, int swap_bytes)
|
|||
qpp->rotvel.x = INTEL_INT(qpp->rotvel.x);
|
||||
qpp->rotvel.y = INTEL_INT(qpp->rotvel.y);
|
||||
qpp->rotvel.z = INTEL_INT(qpp->rotvel.z);
|
||||
qpp->segnum = INTEL_INT(qpp->segnum);
|
||||
}
|
||||
|
||||
vms_matrix_from_quaternion(&objp->orient, &qpp->orient);
|
||||
|
@ -1227,9 +1221,7 @@ void extract_quaternionpos(object *objp, quaternionpos *qpp, int swap_bytes)
|
|||
objp->mtype.phys_info.velocity = qpp->vel;
|
||||
objp->mtype.phys_info.rotvel = qpp->rotvel;
|
||||
|
||||
segnum = qpp->segnum;
|
||||
Assert((segnum >= 0) && (segnum <= Highest_segment_index));
|
||||
obj_relink(objp-Objects, segnum);
|
||||
update_object_seg(objp);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ extern int multi_protocol; // set and determinate used protocol
|
|||
#define MULTI_PROTO_UDP 1 // UDP protocol
|
||||
|
||||
// What version of the multiplayer protocol is this? Increment each time something drastic changes in Multiplayer without the version number changes. Can be reset to 0 each time the version of the game changes
|
||||
#define MULTI_PROTO_VERSION 1
|
||||
#define MULTI_PROTO_VERSION 2
|
||||
// PROTOCOL VARIABLES AND DEFINES - END
|
||||
|
||||
|
||||
|
|
|
@ -4688,7 +4688,6 @@ void net_udp_send_pdata()
|
|||
buf[len] = UPID_PDATA; len++;
|
||||
buf[len] = Player_num; len++;
|
||||
buf[len] = Players[Player_num].connected; len++;
|
||||
buf[len] = Objects[Players[Player_num].objnum].render_type; len++;
|
||||
if (Netgame.ShortPackets)
|
||||
{
|
||||
shortpos spp;
|
||||
|
@ -4701,17 +4700,17 @@ void net_udp_send_pdata()
|
|||
PUT_INTEL_SHORT(buf+len, spp.segment); len += 2;
|
||||
PUT_INTEL_SHORT(buf+len, spp.velx); len += 2;
|
||||
PUT_INTEL_SHORT(buf+len, spp.vely); len += 2;
|
||||
PUT_INTEL_SHORT(buf+len, spp.velz); len += 2; // 23 + 4 = 27
|
||||
PUT_INTEL_SHORT(buf+len, spp.velz); len += 2; // 23 + 3 = 26
|
||||
}
|
||||
else
|
||||
{
|
||||
quaternionpos qpp;
|
||||
memset(&qpp, 0, sizeof(shortpos));
|
||||
memset(&qpp, 0, sizeof(quaternionpos));
|
||||
create_quaternionpos(&qpp, Objects+Players[Player_num].objnum, 0);
|
||||
PUT_INTEL_INT(buf+len, qpp.orient.w); len += 4;
|
||||
PUT_INTEL_INT(buf+len, qpp.orient.x); len += 4;
|
||||
PUT_INTEL_INT(buf+len, qpp.orient.y); len += 4;
|
||||
PUT_INTEL_INT(buf+len, qpp.orient.z); len += 4;
|
||||
PUT_INTEL_SHORT(buf+len, qpp.orient.w); len += 2;
|
||||
PUT_INTEL_SHORT(buf+len, qpp.orient.x); len += 2;
|
||||
PUT_INTEL_SHORT(buf+len, qpp.orient.y); len += 2;
|
||||
PUT_INTEL_SHORT(buf+len, qpp.orient.z); len += 2;
|
||||
PUT_INTEL_INT(buf+len, qpp.pos.x); len += 4;
|
||||
PUT_INTEL_INT(buf+len, qpp.pos.y); len += 4;
|
||||
PUT_INTEL_INT(buf+len, qpp.pos.z); len += 4;
|
||||
|
@ -4720,8 +4719,7 @@ void net_udp_send_pdata()
|
|||
PUT_INTEL_INT(buf+len, qpp.vel.z); len += 4;
|
||||
PUT_INTEL_INT(buf+len, qpp.rotvel.x); len += 4;
|
||||
PUT_INTEL_INT(buf+len, qpp.rotvel.y); len += 4;
|
||||
PUT_INTEL_INT(buf+len, qpp.rotvel.z); len += 4;
|
||||
PUT_INTEL_SHORT(buf+len, qpp.segnum); len += 2; // 54 + 4 = 58
|
||||
PUT_INTEL_INT(buf+len, qpp.rotvel.z); len += 4; // 44 + 3 = 47
|
||||
}
|
||||
|
||||
if (multi_i_am_master())
|
||||
|
@ -4758,7 +4756,6 @@ void net_udp_process_pdata ( ubyte *data, int data_len, struct _sockaddr sender_
|
|||
|
||||
pd.Player_num = data[len]; len++;
|
||||
pd.connected = data[len]; len++;
|
||||
pd.obj_render_type = data[len]; len++;
|
||||
if (Netgame.ShortPackets)
|
||||
{
|
||||
memcpy(&pd.ptype.spp.bytemat, &(data[len]), 9); len += 9;
|
||||
|
@ -4772,10 +4769,10 @@ void net_udp_process_pdata ( ubyte *data, int data_len, struct _sockaddr sender_
|
|||
}
|
||||
else
|
||||
{
|
||||
pd.ptype.qpp.orient.w = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.orient.x = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.orient.y = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.orient.z = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.orient.w = GET_INTEL_SHORT(&data[len]); len += 2;
|
||||
pd.ptype.qpp.orient.x = GET_INTEL_SHORT(&data[len]); len += 2;
|
||||
pd.ptype.qpp.orient.y = GET_INTEL_SHORT(&data[len]); len += 2;
|
||||
pd.ptype.qpp.orient.z = GET_INTEL_SHORT(&data[len]); len += 2;
|
||||
pd.ptype.qpp.pos.x = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.pos.y = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.pos.z = GET_INTEL_INT(&data[len]); len += 4;
|
||||
|
@ -4785,7 +4782,6 @@ void net_udp_process_pdata ( ubyte *data, int data_len, struct _sockaddr sender_
|
|||
pd.ptype.qpp.rotvel.x = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.rotvel.y = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.rotvel.z = GET_INTEL_INT(&data[len]); len += 4;
|
||||
pd.ptype.qpp.segnum = GET_INTEL_SHORT(&data[len]); len += 2;
|
||||
}
|
||||
|
||||
if (multi_i_am_master()) // I am host - must relay this packet to others!
|
||||
|
@ -4870,7 +4866,6 @@ void net_udp_read_pdata_packet(UDP_frame_info *pd)
|
|||
extract_shortpos(TheirObj, &pd->ptype.spp, 0);
|
||||
else
|
||||
extract_quaternionpos(TheirObj, &pd->ptype.qpp, 0);
|
||||
|
||||
if (TheirObj->movement_type == MT_PHYSICS)
|
||||
set_thrust_from_velocity(TheirObj);
|
||||
}
|
||||
|
|
|
@ -68,8 +68,8 @@ void net_udp_send_netgame_update();
|
|||
#define UPID_ENDLEVEL_H 14 // Packet from Host to all Clients containing connect-states and kills information about everyone in the game.
|
||||
#define UPID_ENDLEVEL_C 15 // Packet from Client to Host containing connect-state and kills information from this Client.
|
||||
#define UPID_PDATA 16 // Packet from player containing his movement data.
|
||||
#define UPID_PDATA_S_SIZE 27
|
||||
#define UPID_PDATA_Q_SIZE 58
|
||||
#define UPID_PDATA_S_SIZE 26
|
||||
#define UPID_PDATA_Q_SIZE 47
|
||||
#define UPID_MDATA_PNORM 17 // Packet containing multi buffer from a player. Priority 0,1 - no ACK needed.
|
||||
#define UPID_MDATA_PNEEDACK 18 // Packet containing multi buffer from a player. Priority 2 - ACK needed. Also contains pkt_num
|
||||
#define UPID_MDATA_ACK 19 // ACK packet for UPID_MDATA_P1.
|
||||
|
@ -111,7 +111,6 @@ typedef struct UDP_frame_info
|
|||
ubyte type;
|
||||
ubyte Player_num;
|
||||
ubyte connected;
|
||||
ubyte obj_render_type;
|
||||
union {
|
||||
quaternionpos qpp;
|
||||
shortpos spp;
|
||||
|
|
|
@ -149,7 +149,6 @@ typedef struct quaternionpos {
|
|||
vms_vector pos;
|
||||
vms_vector vel;
|
||||
vms_vector rotvel;
|
||||
short segnum;
|
||||
} __pack__ quaternionpos;
|
||||
|
||||
// This is specific to the shortpos extraction routines in gameseg.c.
|
||||
|
|
|
@ -904,62 +904,62 @@ vms_vector *vm_vec_make(vms_vector *v,fix x,fix y,fix z)
|
|||
return v;
|
||||
}
|
||||
|
||||
// convert vms_quaternion to vms_matrix
|
||||
// convert vms_matrix to vms_quaternion
|
||||
void vms_quaternion_from_matrix(vms_quaternion * q, const vms_matrix * m)
|
||||
{
|
||||
fix tr = m->rvec.x + m->uvec.y + m->fvec.z;
|
||||
if (tr > 0) {
|
||||
fix s = fixmul(fix_sqrt(tr + fl2f(1.0)), fl2f(2.0));
|
||||
q->w = fixmul(fl2f(0.25), s);
|
||||
q->x = fixdiv(m->fvec.y - m->uvec.z, s);
|
||||
q->y = fixdiv(m->rvec.z - m->fvec.x, s);
|
||||
q->z = fixdiv(m->uvec.x - m->rvec.y, s);
|
||||
q->w = fixmul(fl2f(0.25), s) * .5;
|
||||
q->x = fixdiv(m->fvec.y - m->uvec.z, s) * .5;
|
||||
q->y = fixdiv(m->rvec.z - m->fvec.x, s) * .5;
|
||||
q->z = fixdiv(m->uvec.x - m->rvec.y, s) * .5;
|
||||
} else if ((m->rvec.x > m->uvec.y)&(m->rvec.x > m->fvec.z)) {
|
||||
fix s = fixmul(fix_sqrt(fl2f(1.0) + m->rvec.x - m->uvec.y - m->fvec.z), fl2f(2.0));
|
||||
q->w = fixdiv(m->fvec.y - m->uvec.z, s);
|
||||
q->x = fixmul(fl2f(0.25), s);
|
||||
q->y = fixdiv(m->rvec.y + m->uvec.x, s);
|
||||
q->z = fixdiv(m->rvec.z + m->fvec.x, s);
|
||||
q->w = fixdiv(m->fvec.y - m->uvec.z, s) * .5;
|
||||
q->x = fixmul(fl2f(0.25), s) * .5;
|
||||
q->y = fixdiv(m->rvec.y + m->uvec.x, s) * .5;
|
||||
q->z = fixdiv(m->rvec.z + m->fvec.x, s) * .5;
|
||||
} else if (m->uvec.y > m->fvec.z) {
|
||||
fix s = fixmul(fix_sqrt(fl2f(1.0) + m->uvec.y - m->rvec.x - m->fvec.z), fl2f(2.0));
|
||||
q->w = fixdiv(m->rvec.z - m->fvec.x, s);
|
||||
q->x = fixdiv(m->rvec.y + m->uvec.x ,s);
|
||||
q->y = fixmul(fl2f(0.25), s);
|
||||
q->z = fixdiv(m->uvec.z + m->fvec.y , s);
|
||||
q->w = fixdiv(m->rvec.z - m->fvec.x, s) * .5;
|
||||
q->x = fixdiv(m->rvec.y + m->uvec.x ,s) * .5;
|
||||
q->y = fixmul(fl2f(0.25), s) * .5;
|
||||
q->z = fixdiv(m->uvec.z + m->fvec.y , s) * .5;
|
||||
} else {
|
||||
fix s = fixmul(fix_sqrt(fl2f(1.0) + m->fvec.z - m->rvec.x - m->uvec.y), fl2f(2.0));
|
||||
q->w = fixdiv(m->uvec.x - m->rvec.y , s);
|
||||
q->x = fixdiv(m->rvec.z + m->fvec.x , s);
|
||||
q->y = fixdiv(m->uvec.z + m->fvec.y, s);
|
||||
q->z = fixmul(fl2f(0.25), s);
|
||||
q->w = fixdiv(m->uvec.x - m->rvec.y , s) * .5;
|
||||
q->x = fixdiv(m->rvec.z + m->fvec.x , s) * .5;
|
||||
q->y = fixdiv(m->uvec.z + m->fvec.y, s) * .5;
|
||||
q->z = fixmul(fl2f(0.25), s) * .5;
|
||||
}
|
||||
}
|
||||
|
||||
// convert vms_matrix to vms_quaternion
|
||||
// convert vms_quaternion to vms_matrix
|
||||
void vms_matrix_from_quaternion(vms_matrix * m, const vms_quaternion * q)
|
||||
{
|
||||
fix sqw = fixmul(q->w, q->w);
|
||||
fix sqx = fixmul(q->x, q->x);
|
||||
fix sqy = fixmul(q->y, q->y);
|
||||
fix sqz = fixmul(q->z, q->z);
|
||||
fix sqw = fixmul(q->w * 2, q->w * 2);
|
||||
fix sqx = fixmul(q->x * 2, q->x * 2);
|
||||
fix sqy = fixmul(q->y * 2, q->y * 2);
|
||||
fix sqz = fixmul(q->z * 2, q->z * 2);
|
||||
|
||||
fix invs = fixdiv(fl2f(1.0), (sqw + sqx + sqy + sqz));
|
||||
m->rvec.x = fixmul(sqx - sqy - sqz + sqw, invs);
|
||||
m->uvec.y = fixmul(-sqx + sqy - sqz + sqw, invs);
|
||||
m->fvec.z = fixmul(-sqx - sqy + sqz + sqw, invs);
|
||||
|
||||
fix tmp1 = fixmul(q->x, q->y);
|
||||
fix tmp2 = fixmul(q->z, q->w);
|
||||
fix tmp1 = fixmul(q->x * 2, q->y * 2);
|
||||
fix tmp2 = fixmul(q->z * 2, q->w * 2);
|
||||
m->uvec.x = fixmul(fixmul(fl2f(2.0), (tmp1 + tmp2)), invs);
|
||||
m->rvec.y = fixmul(fixmul(fl2f(2.0), (tmp1 - tmp2)), invs);
|
||||
|
||||
tmp1 = fixmul(q->x, q->z);
|
||||
tmp2 = fixmul(q->y, q->w);
|
||||
tmp1 = fixmul(q->x * 2, q->z * 2);
|
||||
tmp2 = fixmul(q->y * 2, q->w * 2);
|
||||
m->fvec.x = fixmul(fixmul(fl2f(2.0), (tmp1 - tmp2)), invs);
|
||||
m->rvec.z = fixmul(fixmul(fl2f(2.0), (tmp1 + tmp2)), invs);
|
||||
|
||||
tmp1 = fixmul(q->y, q->z);
|
||||
tmp2 = fixmul(q->x, q->w);
|
||||
tmp1 = fixmul(q->y * 2, q->z * 2);
|
||||
tmp2 = fixmul(q->x * 2, q->w * 2);
|
||||
m->fvec.y = fixmul(fixmul(fl2f(2.0), (tmp1 + tmp2)), invs);
|
||||
m->uvec.z = fixmul(fixmul(fl2f(2.0), (tmp1 - tmp2)), invs);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue