Difference between writeCompressedPoint and setCompressionPoint
by Drew Parker · in Torque Game Engine · 01/10/2005 (7:48 am) · 5 replies
Hi all,
I'm wondering what the difference between some of the various bitstream functions are, like:
writeCompressedPoint
setCompressionPoint
mathwrite
I noticed that in packUpdate(), ODEItem and Vehicle use two different methods of passing their position and rotation. I found this a bit strange since ODEItem was basically ripped from Vehicle.cc, so they are usually quite similiar.
ODEItem.cc
But in vehicle.cc (where ODEItem gets most of its code), packUpdate is like this:
Vehicle.cc
Any ideas on which is more network efficient? I looked at the docs and the sourcecode, but can't get enough of an idea.
Also, I noticed setCompressionPoint() seems to only be used in writePacketData. Anyone know why this is?
I'm wondering what the difference between some of the various bitstream functions are, like:
writeCompressedPoint
setCompressionPoint
mathwrite
I noticed that in packUpdate(), ODEItem and Vehicle use two different methods of passing their position and rotation. I found this a bit strange since ODEItem was basically ripped from Vehicle.cc, so they are usually quite similiar.
ODEItem.cc
stream->writeAffineTransform(getTransform());
But in vehicle.cc (where ODEItem gets most of its code), packUpdate is like this:
Vehicle.cc
stream->writeCompressedPoint(mRigid.linPosition); mathWrite(*stream, mRigid.angPosition);
Any ideas on which is more network efficient? I looked at the docs and the sourcecode, but can't get enough of an idea.
Also, I noticed setCompressionPoint() seems to only be used in writePacketData. Anyone know why this is?
About the author
#2
Thanks for the answer. Yes, I tried looking through the docs and googling the site but I can't find much stuff on it. I found one forum post by Tim Gift about it, and my feeling is setCompressionPoint only has to do with the control object, and that is why I was only seeing it in packUpdate.
That's a good idea about getting the bit position to compare the two methods. I've been using the netGraph resource a lot to check out my net traffic. Are there any other good ways of checking net usage on a per object or per client level?
I've found my netGraph "received bits" for the clients maxes out at about 237-240, meaning even if I send more stuff at that point with pack/unpackUpdate it won't get through in a timely manner. I need to look into the implementation and find out a bit more about that number, namely what the time unit is (237 bits a tick?), and how often the objects are actually getting updates from the server.
01/12/2005 (7:03 am)
Hi Ben,Thanks for the answer. Yes, I tried looking through the docs and googling the site but I can't find much stuff on it. I found one forum post by Tim Gift about it, and my feeling is setCompressionPoint only has to do with the control object, and that is why I was only seeing it in packUpdate.
That's a good idea about getting the bit position to compare the two methods. I've been using the netGraph resource a lot to check out my net traffic. Are there any other good ways of checking net usage on a per object or per client level?
I've found my netGraph "received bits" for the clients maxes out at about 237-240, meaning even if I send more stuff at that point with pack/unpackUpdate it won't get through in a timely manner. I need to look into the implementation and find out a bit more about that number, namely what the time unit is (237 bits a tick?), and how often the objects are actually getting updates from the server.
#3
void setPointCompression (const Point3F &p)
Sets a reference point for subsequent compressed point writing.
void clearPointCompression ()
Disables compression of point.
void writePointCompressed (const Point3F &p, F32 scale)
Writes a point into the stream, to a precision denoted by scale.
void readPointCompressed (Point3F *p, F32 scale)
Reads a compressed point from the stream, to a precision denoted by scale.
opentnl.sourceforge.net/doxydocs/classTNL_1_1BitStream.html#a26
The get-position approach is the best and most accurate, I'd say.
01/13/2005 (2:47 am)
Ahh, I was thinking about the OpenTNL docs.void setPointCompression (const Point3F &p)
Sets a reference point for subsequent compressed point writing.
void clearPointCompression ()
Disables compression of point.
void writePointCompressed (const Point3F &p, F32 scale)
Writes a point into the stream, to a precision denoted by scale.
void readPointCompressed (Point3F *p, F32 scale)
Reads a compressed point from the stream, to a precision denoted by scale.
opentnl.sourceforge.net/doxydocs/classTNL_1_1BitStream.html#a26
The get-position approach is the best and most accurate, I'd say.
#4
Well, I did some traces through the code to try and get some understanding of how setCompressionPoint and writeCompressedPoint works. Also, if it is better to use that over writeAffineTransformation(). Here is what I found:
Function Call Trace Through Some Net Code
GameConnection::writePacket
The server updating this client connection. First does a bunch of stuff, especially relating to the control object. This is where writePacketData comes into play. After updating the control object, at the very end it makes a call to writePacket(), to update the client with the ghosts.
NetConnection::writePacket
Calls ghostWritePacket below.
NetConnection::ghostWritePacket
Cycles through all ghosts. Find out which ones are in scope, and packs the packet with highest priority info until it is full.
Compression
Well, it looks like TGE's setCompressionPoint(A) just sets a flag and stores the sent point A. Then, when writeCompressPoint(B) is called, it checks to see if the flag was set, and if so does some compession on the new point B. If the flag was not set, it just writes point B as usual.
In GameConnection::writePacket, it is assumed that the control object will set the compression point. If it is not set, the control object's position is used. As far as I can tell, this point is basically a marker to show that all info after it will be compressed for that packet.
That is why, in packUpdate() for the Vehicle class, you see calls to writeCompressPoint(), even though setCompressionPoint() wasn't called in packUpdate(). It's because it was already called by the control objects writePacketData(), or taken care of in GameConnection::writePacket().
So from what I get from reading the forums some, if you set 2 compression points, that is bad, as the second will overwrite the first and mess things up. Also, you can use writeCopmressedPoint() in your packUpdates() whenever you want (if you have a control object?)
Finally, comparing writeAffineTransformation vs. writeCompressPoint:
Here is writeAffineTransform:
It seems only the "less network busy" classes use writeAffineTransformation(), like StaticShape and InteriorInstance.
Some old forums on setCompressionPoint
A post from Tim Gift, and some other stuff on compression points
http://www.garagegames.com/mg/forums/result.thread.php?qt=9934
http://www.garagegames.com/mg/forums/result.thread.php?qt=2781
01/13/2005 (9:06 am)
Ah HA, I totally didn't think to check the OpenTNL docs. :) Thanks Ben.Well, I did some traces through the code to try and get some understanding of how setCompressionPoint and writeCompressedPoint works. Also, if it is better to use that over writeAffineTransformation(). Here is what I found:
Function Call Trace Through Some Net Code
GameConnection::writePacket
The server updating this client connection. First does a bunch of stuff, especially relating to the control object. This is where writePacketData comes into play. After updating the control object, at the very end it makes a call to writePacket(), to update the client with the ghosts.
NetConnection::writePacket
Calls ghostWritePacket below.
NetConnection::ghostWritePacket
Cycles through all ghosts. Find out which ones are in scope, and packs the packet with highest priority info until it is full.
Compression
Well, it looks like TGE's setCompressionPoint(A) just sets a flag and stores the sent point A. Then, when writeCompressPoint(B) is called, it checks to see if the flag was set, and if so does some compession on the new point B. If the flag was not set, it just writes point B as usual.
In GameConnection::writePacket, it is assumed that the control object will set the compression point. If it is not set, the control object's position is used. As far as I can tell, this point is basically a marker to show that all info after it will be compressed for that packet.
That is why, in packUpdate() for the Vehicle class, you see calls to writeCompressPoint(), even though setCompressionPoint() wasn't called in packUpdate(). It's because it was already called by the control objects writePacketData(), or taken care of in GameConnection::writePacket().
So from what I get from reading the forums some, if you set 2 compression points, that is bad, as the second will overwrite the first and mess things up. Also, you can use writeCopmressedPoint() in your packUpdates() whenever you want (if you have a control object?)
Finally, comparing writeAffineTransformation vs. writeCompressPoint:
Here is writeAffineTransform:
mathWrite(*this, pos); QuatF q(matrix); q.normalize(); write(q.x); write(q.y); write(q.z);It makes a mathwrite (which is 3 point write()), and then write()s 3 more values, but all with no compression. So I think it may be better use a compressed point write in general, if you don't need the accuracy. Player, Projectile, Vehicle and Camera all use writeCompressedPoint().
It seems only the "less network busy" classes use writeAffineTransformation(), like StaticShape and InteriorInstance.
Some old forums on setCompressionPoint
A post from Tim Gift, and some other stuff on compression points
http://www.garagegames.com/mg/forums/result.thread.php?qt=9934
http://www.garagegames.com/mg/forums/result.thread.php?qt=2781
#5
01/15/2005 (3:36 pm)
As long as the order of calls to setCompressionPoint wrt to the bitstream is identical, you can call it whenever you like. Just bear in mind that the implications can be wide-reaching (any call to writeCompressedPoint after will be affected!)
Associate Kyle Carter
For setCompressionPoint... have you tried looking at the docs on it?