Datablock pack/unpack problems
by Ian Omroth Hardingham · in Torque Game Engine · 11/25/2003 (12:27 pm) · 7 replies
Hello,
(apologies in advance for the long post)
I have a problem. I added some variables to the PlayerData datablock:
And then added them to packdata
and added them to unpackdata :)
(the printfs are for debugging)
Now, unfortunately the variables are not being transmitted properly. During load, the printfs print the first 3 of my variables. In my definition of the datablock in player.cs these are set to be:
AxisLowerLimit[0] = 5.500000
AxisLowerLimit[1] = 1.000000
AxisLowerLimit[2] = 2.000000
AxisUpperLimit[0] = 11.000000
AxisUpperLimit[1] = 12.000000
AxisUpperLimit[2] = 13.000000
Now here's the actual debug output for the bit during load when it's transmitting the appropriate PlayerData datablock.
I'm guessing it's a type problem, but for the life of me I can't work out what it is. Any help would be greatly appreciated.
Ian
(apologies in advance for the long post)
I have a problem. I added some variables to the PlayerData datablock:
struct PlayerData: public ShapeBaseData
{
...
F32 axisUpperLimit[MAX_AXES];
F32 axisLowerLimit[MAX_AXES];
...And then added them to packdata
void PlayerData::packData(BitStream* stream)
{
...
for (i = 0; i < 3; i ++)
{
stream->writeFloat(axisLowerLimit[i], 8);
stream->writeFloat(axisUpperLimit[i], 8);
Con::printf("outgoing");
Con::printf("%d : %f %f\n", i, axisLowerLimit[i], axisUpperLimit[i]);
}and added them to unpackdata :)
void PlayerData::unpackData(BitStream* stream)
...
for (i=0; i < 3; i ++)
{
axisLowerLimit[i] = stream->readFloat(8);
axisUpperLimit[i] = stream->readFloat(8);
Con::printf("incoming");
Con::printf("%d : %f %f\n", i, axisLowerLimit[i], axisUpperLimit[i]);
}(the printfs are for debugging)
Now, unfortunately the variables are not being transmitted properly. During load, the printfs print the first 3 of my variables. In my definition of the datablock in player.cs these are set to be:
AxisLowerLimit[0] = 5.500000
AxisLowerLimit[1] = 1.000000
AxisLowerLimit[2] = 2.000000
AxisUpperLimit[0] = 11.000000
AxisUpperLimit[1] = 12.000000
AxisUpperLimit[2] = 13.000000
Now here's the actual debug output for the bit during load when it's transmitting the appropriate PlayerData datablock.
*** New Mission: dt/data/missions/dt_junction.mis *** Phase 1: Download Datablocks & Targets Mapping string: MissionStartPhase1Ack to index: 0 outgoing 0 : 5.500000 11.000000 outgoing 1 : 1.000000 12.000000 outgoing 2 : 2.000000 13.000000 incoming 0 : 0.456693 0.921260 incoming 1 : 1.000000 0.913386 incoming 2 : 0.992126 0.905512 outgoing 0 : 0.456693 0.921260 outgoing 1 : 1.000000 0.913386 outgoing 2 : 0.992126 0.905512 incoming 0 : 0.448819 0.913386 incoming 1 : 1.000000 0.905512 incoming 2 : 0.992126 0.897638 Could not locate texture: dt/data/shapes/carl/base.lmale Could not locate texture: dt/data/shapes/carl/base.lmale Validation required for shape: dt/data/shapes/carl/player.dts
I'm guessing it's a type problem, but for the life of me I can't work out what it is. Any help would be greatly appreciated.
Ian
About the author
Designer and lead programmer on Frozen Synapse, Frozen Endzone, and Determinance. Co-owner of Mode 7 Games.
#2
Using 16 bits I get similar but slightly different results:
When I use 32, I get a fatal error in Bitstream.cc @ line 195 saying "out of range write". I looked at that AssertFatal but couldn't get any understanding of the problem.
Should I be using fixed point arithmetic?
Again, thanks for any help.
11/25/2003 (1:34 pm)
Thanks Ben.Using 16 bits I get similar but slightly different results:
outgoing 0 : 5.500000 11.000000 outgoing 1 : 1.000000 12.000000 outgoing 2 : 2.000000 13.000000 incoming 0 : 0.499916 0.999847 incoming 1 : 1.000000 0.999832 incoming 2 : 0.999985 0.999817 outgoing 0 : 0.499916 0.999847 outgoing 1 : 1.000000 0.999832 outgoing 2 : 0.999985 0.999817 incoming 0 : 0.499916 0.999847 incoming 1 : 1.000000 0.999832 incoming 2 : 0.999985 0.999817
When I use 32, I get a fatal error in Bitstream.cc @ line 195 saying "out of range write". I looked at that AssertFatal but couldn't get any understanding of the problem.
Should I be using fixed point arithmetic?
Again, thanks for any help.
#3
So, you don't want to use those methods... try just doing:
stream->write(F32val);
stream->read(&F32val);
11/25/2003 (3:19 pm)
From bitStream.h:// read and write floats... floats are 0 to 1 inclusive, signed floats are -1 to 1 inclusive F32 readFloat(S32 bitCount); F32 readSignedFloat(S32 bitCount); void writeFloat(F32 f, S32 bitCount); void writeSignedFloat(F32 f, S32 bitCount);
So, you don't want to use those methods... try just doing:
stream->write(F32val);
stream->read(&F32val);
#4
and this for the reads:
11/25/2003 (3:25 pm)
Try this for the writes:stream->write(axisLowerLimit[i]);
and this for the reads:
stream->read(&axisLowerLimit[i]);
#5
I tried using stream->write and stream->read but I got the same "out of range write error". However, I don't see any particularly compelling reason not to simply divide my floats by 10, which would put them in the -1,1 brange, and then multiply them up again later.
It would be nice to know what the actual problem is though. I'm still betting I made a type error somewhere.
Thanks again,
Ian
11/25/2003 (6:18 pm)
Thanks for the help guys.I tried using stream->write and stream->read but I got the same "out of range write error". However, I don't see any particularly compelling reason not to simply divide my floats by 10, which would put them in the -1,1 brange, and then multiply them up again later.
It would be nice to know what the actual problem is though. I'm still betting I made a type error somewhere.
Thanks again,
Ian
#6
(Thanks, Mark ;))
11/29/2003 (11:29 am)
You're probably putting too much data into the packet, if I was to guess.(Thanks, Mark ;))
#7
Is it safe to stream->write() a float on a little-endian PC and stream->read() it on a big-endian Mac?
03/12/2007 (10:26 pm)
Doesn't writing the raw float values to the stream a la...stream->write(F32val); stream->read(&F32val);...break cross-platform compatibility?
Is it safe to stream->write() a float on a little-endian PC and stream->read() it on a big-endian Mac?
Associate Kyle Carter
I'd try upping the number of bits allocated to the float. 8 is really much too low if you want your value to pass unmolested. Try 16 or even 32 if you need "full precision".