1
0
Fork 0

Mathias Frhlich:

We should now be able to find
wires or catapults when the ac3d model is loaded without the crease patch
(caused by the much more unstructured scene graph emitted by the old loader).
It should also emit more warnings if the carrier hardware configuration
includes conflicting definitions.
That code is the most intrusive one, it should not be used until you configure
an aircraft carrier as a aimodel. So I think it should be save to apply that
before the release too.
This commit is contained in:
ehofman 2004-12-27 13:21:18 +00:00
parent afe94f63ea
commit 499c702ffb
2 changed files with 102 additions and 44 deletions

View file

@ -92,7 +92,7 @@ bool FGAICarrier::init() {
// Attach a pointer to this carrier class to those objects. // Attach a pointer to this carrier class to those objects.
mark_wires(sel, wire_objects); mark_wires(sel, wire_objects);
mark_cat(sel, catapult_objects); mark_cat(sel, catapult_objects);
mark_solid(sel, solid_objects, false); mark_solid(sel, solid_objects);
return true; return true;
} }
@ -129,14 +129,18 @@ void FGAICarrier::mark_nohot(ssgEntity* e) {
} }
} }
bool FGAICarrier::mark_wires(ssgEntity* e, const list<string>& wire_objects) { bool FGAICarrier::mark_wires(ssgEntity* e, const list<string>& wire_objects, bool mark) {
bool found = false; bool found = false;
if (e->isAKindOf(ssgTypeBranch())) { if (e->isAKindOf(ssgTypeBranch())) {
ssgBranch* br = (ssgBranch*)e; ssgBranch* br = (ssgBranch*)e;
ssgEntity* kid; ssgEntity* kid;
list<string>::const_iterator it;
for (it = wire_objects.begin(); it != wire_objects.end(); ++it)
mark = mark || (e->getName() && (*it) == e->getName());
for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() ) for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
found = mark_wires(kid, wire_objects) || found; found = mark_wires(kid, wire_objects, mark) || found;
if (found) if (found)
br->setTraversalMaskBits(SSGTRAV_HOT); br->setTraversalMaskBits(SSGTRAV_HOT);
@ -144,16 +148,31 @@ bool FGAICarrier::mark_wires(ssgEntity* e, const list<string>& wire_objects) {
} else if (e->isAKindOf(ssgTypeLeaf())) { } else if (e->isAKindOf(ssgTypeLeaf())) {
list<string>::const_iterator it; list<string>::const_iterator it;
for (it = wire_objects.begin(); it != wire_objects.end(); ++it) { for (it = wire_objects.begin(); it != wire_objects.end(); ++it) {
if (e->getName() && (*it) == e->getName()) { if (mark || (e->getName() && (*it) == e->getName())) {
e->setTraversalMaskBits(SSGTRAV_HOT); e->setTraversalMaskBits(SSGTRAV_HOT);
e->setUserData( FGAICarrierHardware::newWire( this ) ); ssgBase* ud = e->getUserData();
ssgLeaf *l = (ssgLeaf*)e; if (ud) {
if ( l->getNumLines() != 1 ) { FGAICarrierHardware* ch = dynamic_cast<FGAICarrierHardware*>(ud);
SG_LOG(SG_GENERAL, SG_ALERT, if (ch) {
"AICarrier: Found wires not modelled with exactly one line!"); SG_LOG(SG_GENERAL, SG_WARN,
"AICarrier: Carrier hardware gets marked twice!\n"
" You have propably a whole branch marked as"
" a wire which also includes other carrier hardware."
);
} else {
SG_LOG(SG_GENERAL, SG_ALERT,
"AICarrier: Found user data attached to a leaf node which "
"should be marked as a wire!\n ****Skipping!****");
}
} else {
e->setUserData( FGAICarrierHardware::newWire( this ) );
ssgLeaf *l = (ssgLeaf*)e;
if ( l->getNumLines() != 1 ) {
SG_LOG(SG_GENERAL, SG_ALERT,
"AICarrier: Found wires not modelled with exactly one line!");
}
found = true;
} }
found = true;
} }
} }
} }
@ -168,7 +187,7 @@ bool FGAICarrier::mark_solid(ssgEntity* e, const list<string>& solid_objects, bo
list<string>::const_iterator it; list<string>::const_iterator it;
for (it = solid_objects.begin(); it != solid_objects.end(); ++it) for (it = solid_objects.begin(); it != solid_objects.end(); ++it)
mark = mark || e->getName() && (*it) == e->getName(); mark = mark || (e->getName() && (*it) == e->getName());
for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() ) for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
found = mark_solid(kid, solid_objects, mark) || found; found = mark_solid(kid, solid_objects, mark) || found;
@ -181,21 +200,42 @@ bool FGAICarrier::mark_solid(ssgEntity* e, const list<string>& solid_objects, bo
for (it = solid_objects.begin(); it != solid_objects.end(); ++it) { for (it = solid_objects.begin(); it != solid_objects.end(); ++it) {
if (mark || (e->getName() && (*it) == e->getName())) { if (mark || (e->getName() && (*it) == e->getName())) {
e->setTraversalMaskBits(SSGTRAV_HOT); e->setTraversalMaskBits(SSGTRAV_HOT);
e->setUserData( FGAICarrierHardware::newSolid( this ) ); ssgBase* ud = e->getUserData();
found = true; if (ud) {
FGAICarrierHardware* ch = dynamic_cast<FGAICarrierHardware*>(ud);
if (ch) {
SG_LOG(SG_GENERAL, SG_WARN,
"AICarrier: Carrier hardware gets marked twice!\n"
" You have propably a whole branch marked solid"
" which also includes other carrier hardware."
);
} else {
SG_LOG(SG_GENERAL, SG_ALERT,
"AICarrier: Found user data attached to a leaf node which "
"should be marked solid!\n ****Skipping!****");
}
} else {
e->setUserData( FGAICarrierHardware::newSolid( this ) );
found = true;
}
} }
} }
} }
return found; return found;
} }
bool FGAICarrier::mark_cat(ssgEntity* e, const list<string>& cat_objects) { bool FGAICarrier::mark_cat(ssgEntity* e, const list<string>& cat_objects, bool mark) {
bool found = false; bool found = false;
if (e->isAKindOf(ssgTypeBranch())) { if (e->isAKindOf(ssgTypeBranch())) {
ssgBranch* br = (ssgBranch*)e; ssgBranch* br = (ssgBranch*)e;
ssgEntity* kid; ssgEntity* kid;
list<string>::const_iterator it;
for (it = cat_objects.begin(); it != cat_objects.end(); ++it)
mark = mark || (e->getName() && (*it) == e->getName());
for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() ) for ( kid = br->getKid(0); kid != NULL ; kid = br->getNextKid() )
found = mark_cat(kid, cat_objects) || found; found = mark_cat(kid, cat_objects, mark) || found;
if (found) if (found)
br->setTraversalMaskBits(SSGTRAV_HOT); br->setTraversalMaskBits(SSGTRAV_HOT);
@ -203,33 +243,51 @@ bool FGAICarrier::mark_cat(ssgEntity* e, const list<string>& cat_objects) {
} else if (e->isAKindOf(ssgTypeLeaf())) { } else if (e->isAKindOf(ssgTypeLeaf())) {
list<string>::const_iterator it; list<string>::const_iterator it;
for (it = cat_objects.begin(); it != cat_objects.end(); ++it) { for (it = cat_objects.begin(); it != cat_objects.end(); ++it) {
if (e->getName() && (*it) == e->getName()) { if (mark || (e->getName() && (*it) == e->getName())) {
e->setTraversalMaskBits(SSGTRAV_HOT); e->setTraversalMaskBits(SSGTRAV_HOT);
e->setUserData( FGAICarrierHardware::newCatapult( this ) ); ssgBase* ud = e->getUserData();
ssgLeaf *l = (ssgLeaf*)e; if (ud) {
if ( l->getNumLines() != 1 ) { FGAICarrierHardware* ch = dynamic_cast<FGAICarrierHardware*>(ud);
SG_LOG(SG_GENERAL, SG_ALERT, if (ch) {
"AICarrier: Found a cat not modelled with exactly one line!"); SG_LOG(SG_GENERAL, SG_WARN,
} "AICarrier: Carrier hardware gets marked twice!\n"
// Now some special code to make sure the cat points in the right " You have propably a whole branch marked as"
// direction. The 0 index must be the backward end, the 1 index " a catapult which also includes other carrier hardware."
// the forward end. );
// Forward is positive x-direction in our 3D model, also the model } else {
// as such is flattened when it is loaded, so we do not need to care SG_LOG(SG_GENERAL, SG_ALERT,
// for transforms ... "AICarrier: Found user data attached to a leaf node which "
short v[2]; "should be marked as a catapult!\n ****Skipping!****");
l->getLine(0, v, v+1 ); }
sgVec3 ends[2]; } else {
for (int k=0; k<2; ++k) e->setUserData( FGAICarrierHardware::newCatapult( this ) );
sgCopyVec3( ends[k], l->getVertex( v[k] ) ); ssgLeaf *l = (ssgLeaf*)e;
if ( l->getNumLines() != 1 ) {
SG_LOG(SG_GENERAL, SG_ALERT,
"AICarrier: Found a cat not modelled with exactly "
"one line!");
} else {
// Now some special code to make sure the cat points in the right
// direction. The 0 index must be the backward end, the 1 index
// the forward end.
// Forward is positive x-direction in our 3D model, also the model
// as such is flattened when it is loaded, so we do not need to
// care for transforms ...
short v[2];
l->getLine(0, v, v+1 );
sgVec3 ends[2];
for (int k=0; k<2; ++k)
sgCopyVec3( ends[k], l->getVertex( v[k] ) );
// When the 1 end is behind the 0 end, swap the coordinates. // When the 1 end is behind the 0 end, swap the coordinates.
if (ends[0][0] < ends[1][0]) { if (ends[0][0] < ends[1][0]) {
sgCopyVec3( l->getVertex( v[0] ), ends[1] ); sgCopyVec3( l->getVertex( v[0] ), ends[1] );
sgCopyVec3( l->getVertex( v[1] ), ends[0] ); sgCopyVec3( l->getVertex( v[1] ), ends[0] );
} }
found = true; found = true;
}
}
} }
} }
} }

View file

@ -90,9 +90,9 @@ private:
void update(double dt); void update(double dt);
void mark_nohot(ssgEntity*); void mark_nohot(ssgEntity*);
bool mark_wires(ssgEntity*, const list<string>&); bool mark_wires(ssgEntity*, const list<string>&, bool = false);
bool mark_cat(ssgEntity*, const list<string>&); bool mark_cat(ssgEntity*, const list<string>&, bool = false);
bool mark_solid(ssgEntity*, const list<string>&, bool); bool mark_solid(ssgEntity*, const list<string>&, bool = false);
list<string> solid_objects; // List of solid object names list<string> solid_objects; // List of solid object names
list<string> wire_objects; // List of wire object names list<string> wire_objects; // List of wire object names