TGE1.4] custom Item()
by So Yamaoka · in Torque Game Engine · 11/14/2005 (11:36 am) · 7 replies
Hi,
I have been working with TGE 1.3 and now adapting the custom codes to the new version of TGE (gotten via CVS.) It is almost done except one thing. TGE crashes when I quit the mission with the console message, "Torque-MacCarb-Debug has exited due to signal 11 (SIGSEGV)." Consulting with the gdb, it is trying to refer an illegal datablock. The thing is, the datablock itself is instantiated properly but the variables inside the datablock are not. This is a general idea of the proble I'm facing at.
Here is the details.
I have embedded a custom particle system into ItemData() and Item(). What I want to do is to let a player has the custom particle emitter just like a weapon. It is something similar to this:
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=6387
There're reasons I want to do this in the source codes instead of scripts but I'd like to omit the explanation here. I've confirmed that the custom particle emitter is properly working just like a TGE's original particle emitter. The problem comes when I want to make it item. OK, the additional codes look like this. In item.h:
The implementation is followed in the item.cc.
The seg fault happens when it is trying to refer the datablock inside mNcEmitter, which is ncEmitterData. ncEmitterData itself has an appropriated memory allocated but the variables inside ncEmitterData are not.
Here's an additional information which might tell something about the problem. I've put printout messages into the constructors of both Item and ItemData but they are never called. The previous version (TGE 1.3) did call them. Has any significant changes been made around shapeImage or shapeBase?
Ok that's about it, thanks for reading. Sorry for a kind of loose, scattered explanation but I can't really point out what's going on here. I am happy to give out further imformation if it is necessary, and happy to (try to) clarify my crappy languages.
I'd greatly appreciate any suggestions. I have been chasing this for 3 days and now I ran out of ideas.
So
I have been working with TGE 1.3 and now adapting the custom codes to the new version of TGE (gotten via CVS.) It is almost done except one thing. TGE crashes when I quit the mission with the console message, "Torque-MacCarb-Debug has exited due to signal 11 (SIGSEGV)." Consulting with the gdb, it is trying to refer an illegal datablock. The thing is, the datablock itself is instantiated properly but the variables inside the datablock are not. This is a general idea of the proble I'm facing at.
Here is the details.
I have embedded a custom particle system into ItemData() and Item(). What I want to do is to let a player has the custom particle emitter just like a weapon. It is something similar to this:
www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=6387
There're reasons I want to do this in the source codes instead of scripts but I'd like to omit the explanation here. I've confirmed that the custom particle emitter is properly working just like a TGE's original particle emitter. The problem comes when I want to make it item. OK, the additional codes look like this. In item.h:
struct ItemData: public ShapeBaseData {
...
// MODIFIED: Nov 11, 2005. by So
NcParticleEmitterData* ncEmitterData;
...
// MODIFIED: Nov 11, 2005. by So
bool preload( bool server, char errorBuffer[256] );
// the following is original.
static void initPersistFields();
virtual void packData(BitStream* stream);
virtual void unpackData(BitStream* stream);
};
class Item: public ShapeBase
{
...
// MODIFIED: Nov 11, 2005. by So
NcParticleEmitter* mNcEmitter;
...
// MODIFIED: Nov 11, 2005. by So
void updateNcEmitter( F32 dt ); // to update the emitter
...
// MODIFIED: Nov 11, 2005. by So
void advanceTime(F32 dt); // this calls updateNcEmitter
// the following is original.
void processTick(const Move *move);
void interpolateTick(F32 delta);
void setTransform(const MatrixF &mat);
void renderImage(SceneState *state, SceneRenderImage *image);
U32 packUpdate (NetConnection *conn, U32 mask, BitStream *stream);
void unpackUpdate(NetConnection *conn, BitStream *stream);
};The implementation is followed in the item.cc.
The seg fault happens when it is trying to refer the datablock inside mNcEmitter, which is ncEmitterData. ncEmitterData itself has an appropriated memory allocated but the variables inside ncEmitterData are not.
Here's an additional information which might tell something about the problem. I've put printout messages into the constructors of both Item and ItemData but they are never called. The previous version (TGE 1.3) did call them. Has any significant changes been made around shapeImage or shapeBase?
Ok that's about it, thanks for reading. Sorry for a kind of loose, scattered explanation but I can't really point out what's going on here. I am happy to give out further imformation if it is necessary, and happy to (try to) clarify my crappy languages.
I'd greatly appreciate any suggestions. I have been chasing this for 3 days and now I ran out of ideas.
So
#2
11/14/2005 (5:52 pm)
Is the emitter deleted when the object is removed?
#3
11/14/2005 (10:34 pm)
Yes it is. Here's all the custom codes I've added to item.cc.ItemData()::ItemData()
{
...
ncEmitterData = NULL;
ncEmitterHeight = 0.0f;
ncEmitterId = 0;
...
}
void ItemData::initPersistFields()
{
...
addField("ncEmitterData", TypeNcParticleEmitterDataPtr, Offset(ncEmitterData, ItemData));
addField("ncEmitterHeight", TypeF32, Offset(ncEmitterHeight, ItemData));
...
}
void ItemData::packData(BitStream* stream)
{
...
if( stream->writeFlag(ncEmitterHeight!=0.0) ){
stream->writeFloat( ncEmitterHeight, 7 );
std::cout << "ItemData::pack: ncEmitterHeight = " << ncEmitterHeight << std::endl;
}
if( stream->writeFlag( ncEmitterData ) ){
stream->writeRangedU32( ncEmitterData->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast );
std::cout << "ItemData::pack: ncEmitterId = " << ncEmitterData->getId() << std::endl;
}...
}
void ItemData::unpackData(BitStream* stream)
{
...
if( stream->readFlag() ){
ncEmitterHeight = stream->readFloat(7);
std::cout << "ItemData::unpack: ncEmitterHeight = " << ncEmitterHeight << std::endl;
} else ncEmitterHeight = 0.0f;
if( stream->readFlag() ){
ncEmitterId = (S32) stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast );
std::cout << "ItemData::unpack: ncEmitterId = " << ncEmitterId << std::endl;
}
...
}Item::Item()
{
...
mNcEmitter = NULL;
...
}
bool Item::onAdd()
{
...
if( isClientObject() ){
if( mDataBlock->ncEmitterData ){
std::cout << "ncEmitter is instantiated." << std::endl;
mNcEmitter = new NcParticleEmitter;
mNcEmitter->onNewDataBlock( mDataBlock->ncEmitterData );
if( !mNcEmitter->registerObject() )
{
Con::warnf( ConsoleLogEntry::General, "Could not register ncEmitter for class: %s", mDataBlock->getName());
delete mNcEmitter;
mNcEmitter = NULL;
}
}
}
...
}
void Item::onRemove()
{
...
if( isClientObject() ){
if( mNcEmitter ){
std::cout << "ncEmitter is deleted." << std::endl;
mNcEmitter->deleteWhenEmpty();
mNcEmitter = NULL;
}
}
...
}
void Item::advanceTime( F32 dt )
{
Parent::advanceTime( dt );
updateNcEmitter( dt );
}
void Item::updateNcEmitter( F32 dt )
{
if( !mNcEmitter ) return;
Point3F emitPoint, emitVelocity;
Point3F emitAxis(0, 0, 1);
getTransform().mulV(emitAxis);
getTransform().getColumn(3, &emitPoint);
emitVelocity = emitAxis * mVelocity;
emitPoint += Point3F( 0.0, 0.0, mDataBlock->ncEmitterHeight );
mNcEmitter->emitParticles( emitPoint, emitPoint,
emitAxis,
emitVelocity, (U32)(dt * 1000.0f));
}
#4
Sometimes, I get the following assertion instead of the seg fault. Anybody has any ideas regarding the assertion?
Fatal: (../engine/sim/sceneObject.cc @ 826) Error, a GameBase (9799b00) isn't properly out of the bins!
DEBUG_BREAK
11/15/2005 (12:56 am)
OK, the problem should lurk behind either my custom particle system or the custom codes I've added to shapeImage.cc. I was able to make the TGE's original particle emitter an item without any seg fault...Sometimes, I get the following assertion instead of the seg fault. Anybody has any ideas regarding the assertion?
Fatal: (../engine/sim/sceneObject.cc @ 826) Error, a GameBase (9799b00) isn't properly out of the bins!
DEBUG_BREAK
#5
I guess the question is how to let ShapeBase/ShapeBaseImage handle a custom object. Am I missing something or doing something stupid? Are there any other parts should be modified?
11/15/2005 (2:06 pm)
I duplicated the TGE's original particle system and renamed them to NcParticle. Then, in shapeBase.h and shapeImage.cc, I also duplicated the parts related to particle emitters, and renamed to NcParticle. The following assertion kept coming up.Fatal: (../engine/sim/sceneObject.cc @ 826) Error, a GameBase (961a460) isn't properly out of the bins! DEBUG_BREAK!
I guess the question is how to let ShapeBase/ShapeBaseImage handle a custom object. Am I missing something or doing something stupid? Are there any other parts should be modified?
#6
11/18/2005 (10:34 am)
Make sure that your Item::onRemove() is calling the Parent::onRemove() for both the server and the client sides. IIRC, ShapeBase::onRemove() takes care of unlinking the object from the world, and SimObject::onRemove() handles unregistering the object from the Simulation.
#7
I've found out that the assertion comes up when the total number of the particles, both torque's original and mine, exceeds the certain amount. I can't tell the exact number since it is the combination of the particle's life time and ejection rate. I couldn't figure it out why, however the assertion is gone by putting the unregisterObject in item::onRemove() manually.
I thought all registered objects will be unregistered by some upper level manager but not true in some situations?
12/02/2005 (10:16 pm)
I'm following up the situation since I've initiated the this thread. Thanks for the reply Stephen. I'm sure that the Parent::onRemove() is called on both sides.I've found out that the assertion comes up when the total number of the particles, both torque's original and mine, exceeds the certain amount. I can't tell the exact number since it is the combination of the particle's life time and ejection rate. I couldn't figure it out why, however the assertion is gone by putting the unregisterObject in item::onRemove() manually.
I thought all registered objects will be unregistered by some upper level manager but not true in some situations?
Torque Owner So Yamaoka
So