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:
zicodxx 2012-05-26 17:53:05 +02:00
parent 46f4a9e285
commit 1d68e2d3ba
8 changed files with 54 additions and 68 deletions

View file

@ -4,6 +4,7 @@ D1X-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
--------

View file

@ -77,7 +77,7 @@ __pack__ vms_matrix;
// Quaternion structure
typedef struct vms_quaternion
{
fix w, x, y, z;
signed short w, x, y, z;
} __pack__ vms_quaternion;

View file

@ -1099,14 +1099,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);
@ -1116,20 +1114,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);
@ -1139,7 +1134,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);
@ -1148,9 +1142,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);
}

View file

@ -65,7 +65,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

View file

@ -4536,8 +4536,7 @@ 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++; // 4
buf[len] = Players[Player_num].connected; len++; // 3
if (Netgame.ShortPackets)
{
shortpos spp;
@ -4550,17 +4549,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;
@ -4569,8 +4568,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())
@ -4607,7 +4605,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;
@ -4621,10 +4618,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;
@ -4634,7 +4631,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!
@ -4715,7 +4711,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);
}

View file

@ -67,8 +67,8 @@ void net_udp_send_mdata_direct(ubyte *data, int data_len, int pnum, int priority
#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.
@ -110,7 +110,6 @@ typedef struct UDP_frame_info
ubyte type;
ubyte Player_num;
ubyte connected;
ubyte obj_render_type;
union {
quaternionpos qpp;
shortpos spp;

View file

@ -145,7 +145,6 @@ typedef struct quaternionpos {
vms_vector pos;
vms_vector vel;
vms_vector rotvel;
short segnum;
} __pack__ quaternionpos;

View file

@ -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);
}