Hiding Meshes v2
by Fyodor -bank- Osokin · 09/24/2008 (6:49 am) · 46 comments
This is a second (improved) version of Hiding Meshes resource made for TGEA (can be easily back-ported to TGE with minor changes).
This resource allows you to toggle visibility of parts of your ShapeBase-based objects (like Vehicle or Player), like Clothes, Armor, etc.
This requires that your model is made with separate meshes, e.g. not with single object.
From original resource's description:
------------------------------------------------------
Notice 1:
All changes are covered with #ifdef / #endif, so it's quite easy to implemented into your engine and to toggle this resource on/off via simple define in torqueConfig.h by commenting/uncommenting:
torqueConfig.h
Another major change, that it doesn't apply changes immediately, you need to force updating network by calling
I've made it in a such way to save network. See example below.
------------------------------------------------------
Console Methods:
------------------------------------------------------
Notice 2:
This implementation is a bit different from original - the main thing is:
(quote from comments of original resource - by Orion Elenzil)
You will need to set to true in case you have most of meshes invisible with only "some" visible. Otherwise keep it "false" (default).
------------------------------------------------------
Source changes:
tsShapeInstance.h
tsShapeInstance.cc
tsAnimate.cc
ShapeBase.h
ShapeBase.cc
This is a small improvement - if no meshes visible, the object will not be rendered! Another way of being "hidden" in game :)
Paste the following code at the end of shapeBase.cpp file:
Notice 3:
This is network-safe implementation, but in case you catch anything strange - please share with the community, fixes and improvements are welcomed!
This resource allows you to toggle visibility of parts of your ShapeBase-based objects (like Vehicle or Player), like Clothes, Armor, etc.
This requires that your model is made with separate meshes, e.g. not with single object.
From original resource's description:
Quote:The main use is to simulate Raven's Ghoul system, wherein 3-4 models are used to represent hundreds of possibilities. This way, your model can contain a standard torso, a torso with platemail, a torso with chainmail, etc. All torsos are skinned the same, on one model. When loading the character, you turn off all meshes but one. When the player puts on a piece of armor, you can then turn off the standard torso, and turn on the armored one.
------------------------------------------------------
Notice 1:
All changes are covered with #ifdef / #endif, so it's quite easy to implemented into your engine and to toggle this resource on/off via simple define in torqueConfig.h by commenting/uncommenting:
// Hidden Meshes v2 resource #define _res__hideMeshResource
Another major change, that it doesn't apply changes immediately, you need to force updating network by calling
%obj.updateMeshes();after you have done toggling meshes.
I've made it in a such way to save network. See example below.
------------------------------------------------------
Console Methods:
ConsoleMethod( ShapeBase, updateMeshes, void, 2, 2, "() sets HideMesh mask for network updates") ConsoleMethod( ShapeBase, MeshOffAll, void, 2, 2, "() Hide all meshes") ConsoleMethod( ShapeBase, MeshOnAll, void, 2, 2, "() Show all meshes") ConsoleMethod( ShapeBase, MeshOff, void, 3, 3, "(string meshname)") ConsoleMethod( ShapeBase, MeshOn, void, 3, 3, "(string meshname)")Debug console methods:
ConsoleMethod( ShapeBase, MeshOffList, void, 2, 2, "() List all not visible meshes") ConsoleMethod( ShapeBase, MeshOnList, void, 2, 2, "List all visible meshes") ConsoleMethod( ShapeBase, ModelDump, void, 2, 2, "() Dump known info on a model")Usage:
%obj.MeshOffAll(); // Hide all meshes, so we can switch "on" only needed ones.
%obj.MeshOn("head"); // We need a head
%obj.MeshOn("armorTorso"); // armored torso
%obj.MeshOn("hips"); // hips part
%obj.MeshOn("legs"); // legs
%obj.MeshOn("armorBoots"); // armored boots
%obj.updateMeshes(); // set netMask so server will send changes on this object to all connections in scope
%obj.MeshOnList(); // looking at the console to check if all okay------------------------------------------------------
Notice 2:
This implementation is a bit different from original - the main thing is:
(quote from comments of original resource - by Orion Elenzil)
Quote:If you're going to have mostly hidden meshes with only a few visible ones...You can set it via datablock:
%datablock.invertHiddenMeshes = true;This doesn't affect the scripting, you still do MeshOn() to make mesh visible. All the stuff is handled via engine for network saving.
You will need to set to true in case you have most of meshes invisible with only "some" visible. Otherwise keep it "false" (default).
------------------------------------------------------
Source changes:
/// These are set up by default based on shape data
struct MeshObjectInstance : ObjectInstance
{
#ifdef _res__hideMeshResource
bool forceHidden;
#endif
TSMesh * const * meshList; ///< one mesh per detail level... Null entries allowed.void TSShapeInstance::buildInstanceData(TSShape * _shape, bool loadMaterials)
{
......
else
objInst->meshList = NULL;
objInst->object = obj;
#ifdef _res__hideMeshResource
objInst->forceHidden = false;
#endif
}
// construct ifl material objectsvoid TSShapeInstance::animateVisibility(S32 ss)
{
......
S32 b = a + mShape->subShapeNumObjects[ss];
for (i=a; i<b; i++)
#ifdef _res__hideMeshResource
if (mMeshObjects[i].forceHidden)
mMeshObjects[i].visible = 0.f;
else
#endif
if (beenSet.test(i))
mMeshObjects[i].visible = mShape->objectStates[i].vis;struct ShapeBaseData : public GameBaseData {
......
bool shadowEnable;
#ifdef _res__hideMeshResource
bool invertHiddenMeshes;
#endif
bool shadowCanMove;
bool shadowCanAnimate;InvincibleMask = Parent::NextFreeMask << 6,
SkinMask = Parent::NextFreeMask << 7,
#ifdef _res__hideMeshResource
HideMeshMask = Parent::NextFreeMask << 8,
SoundMaskN = Parent::NextFreeMask << 9, ///< Extends + MaxSoundThreads bits
#else
SoundMaskN = Parent::NextFreeMask << 8, ///< Extends + MaxSoundThreads bits
#endif
ThreadMaskN = SoundMaskN << MaxSoundThreads, ///< Extends + MaxScriptThreads bitsvoid setSkinName(const char*);
const char* getSkinName();
/// @}
#ifdef _res__hideMeshResource
/// @name HideMesh v2 resource
/// @{
Vector<S32> mToggledMeshes; ///< The list of toggled meshes
protected:
void updateToggledMeshes(); ///< Client-side function to update visibility of meshes in TSShapeInstance
bool isMeshToggled(S32 node); ///< Returns true if the mesh is in toggled list
public:
void MeshOffAll(); ///< Hide all meshes
void MeshOnAll(); ///< Show all meshes
void MeshToggleOnAll(); ///< Add all meshes to "toggled" list
void MeshToggleOffAll(); ///< Clear "toggled" list, all meshes in default state
void MeshOn(const char *); ///< Show mesh
void MeshOff(const char *); ///< Hide mesh
void MeshClearFromToggled(const char *); ///< Clear specified mesh from toggled list
void MeshAddToToggled(const char *); ///< Add specified mesh to toggled list
#ifndef TORQUE_SHIPPING
void MeshListToggled(); ///< Dump list of toggled meshes into console
void MeshListNonToggled(); ///< Dump list of non-toggled meshes into console
void MeshOffList(); ///< Dump list of hidden meshes
void MeshOnList(); ///< Dump list of visible meshes
void ModelDump(); ///< Save ./Model.dump report from TSDump
#endif
const char * getMeshList(bool); ///< Returns the space-separated list of meshes (visible or hidden)
const char * getMaterialList(); ///< Returns material list
/// @}
public:
#endif // #ifdef _res__hideMeshResource
/// @name Basic attributesShapeBaseData::ShapeBaseData()
{
#ifdef _res__hideMeshResource
invertHiddenMeshes = false;
#endif
shadowEnable = false;
shadowCanMove = false;void ShapeBaseData::initPersistFields()
{
......
addGroup("Render");
#ifdef _res__hideMeshResource
addField("invertHiddenMeshes", TypeBool, Offset(invertHiddenMeshes, ShapeBaseData));
#endif
addField("shapeFile", TypeFilename, Offset(shapeName, ShapeBaseData));
addField("emap", TypeBool, Offset(emap, ShapeBaseData));
endGroup("Render");void ShapeBaseData::packData(BitStream* stream)
{
Parent::packData(stream);
if(stream->writeFlag(computeCRC))
stream->write(mCRC);
#ifdef _res__hideMeshResource
stream->writeFlag(invertHiddenMeshes);
#endif
stream->writeFlag(shadowEnable);
stream->writeFlag(shadowCanMove);void ShapeBaseData::unpackData(BitStream* stream)
{
Parent::unpackData(stream);
computeCRC = stream->readFlag();
if(computeCRC)
stream->read(&mCRC);
#ifdef _res__hideMeshResource
invertHiddenMeshes = stream->readFlag();
#endif
shadowEnable = stream->readFlag();
shadowCanMove = stream->readFlag();This is a small improvement - if no meshes visible, the object will not be rendered! Another way of being "hidden" in game :)
bool ShapeBase::prepRenderImage(SceneState* state, const U32 stateKey,
const U32 startZone, const bool modifyBaseState)
{
...
if( ( getDamageState() == Destroyed ) && ( !mDataBlock->renderWhenDestroyed ) )
{
PROFILE_END();
return false;
}
#ifdef _res__hideMeshResource
// HideMesh additions / optimization
// We don't need to to prepRenderImage if no meshes visible
if (mShapeInstance)
{
if (!mDataBlock->invertHiddenMeshes)
{
if (mToggledMeshes.size() == mShapeInstance->mMeshObjects.size())
{
PROFILE_END();
return false;
}
}
else
{
if (mToggledMeshes.size()==0)
{
PROFILE_END();
return false;
}
}
}
#endif // #ifdef _res__hideMeshResource
// Select detail levels on mounted items
// but... always draw the control object's mounted images
// in high detail (I can't believe I'm commenting this hack :)
F32 saveError = TSShapeInstance::smScreenError;U32 ShapeBase::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
{
......
if(!stream->writeFlag(mask & (NameMask | DamageMask | SoundMask |
#ifdef _res__hideMeshResource
HideMeshMask |
#endif
ThreadMask | ImageMask | CloakMask | MountedMask | InvincibleMask | ShieldMask | SkinMask)))
......
// Group some of the uncommon stuff together.
if (stream->writeFlag(mask & (NameMask | ShieldMask | CloakMask | InvincibleMask | SkinMask
#ifdef _res__hideMeshResource
| HideMeshMask
#endif
))) {
......
stream->write(mInvincibleSpeed);
}
#ifdef _res__hideMeshResource
if (stream->writeFlag(mask & HideMeshMask)) {
stream->writeInt(mToggledMeshes.size(), 7);
for(int x = 0; x < mToggledMeshes.size(); x++)
stream->writeInt(mToggledMeshes[x], 8);
}
#endif
if (stream->writeFlag(mask & SkinMask)) {void ShapeBase::unpackUpdate(NetConnection *con, BitStream *stream)
{
......
setupInvincibleEffect(time, speed);
}
#ifdef _res__hideMeshResource
if (stream->readFlag())
{ // HideMeshMask
mToggledMeshes.clear();
S32 count = stream->readInt(7);
for(S32 x = 0; x < count; x++)
mToggledMeshes.push_back(stream->readInt(8));
//Con::warnf("hiddenMesh::: %d", count);
updateToggledMeshes();
}
#endif
if (stream->readFlag()) { // SkinMaskPaste the following code at the end of shapeBase.cpp file:
#ifdef _res__hideMeshResource
//--------------------------------------------------------------------------
// Start of HideMesh v2 Part
//--------------------------------------------------------------------------
void ShapeBase::updateToggledMeshes()
{
if(!isGhost())
{
Con::errorf("ShapeBase::updateToggledMeshes() not allowed to be called on server!");
return;
}
if(!mShapeInstance)
return;
S32 s = mShapeInstance->mMeshObjects.size();
if (!mDataBlock->invertHiddenMeshes)
{
for(S32 x = 0; x < s; x++)
{
S32 nameIndex = mShapeInstance->mMeshObjects[x].object->nameIndex;
F32 visible = 1.f;
if(isMeshToggled(nameIndex))
visible = 0.f;
mShapeInstance->mMeshObjects[x].visible = visible;
mShapeInstance->mMeshObjects[x].forceHidden = (visible == 0.f);
}
}
else
{
for(S32 x = 0; x < s; x++)
{
S32 nameIndex = mShapeInstance->mMeshObjects[x].object->nameIndex;
F32 visible = 0.f;
if (isMeshToggled(nameIndex))
visible = 1.f;
mShapeInstance->mMeshObjects[x].visible = visible;
mShapeInstance->mMeshObjects[x].forceHidden = (visible == 0.f);
}
}
}
bool ShapeBase::isMeshToggled(S32 node)
{
for(int x = 0; x < mToggledMeshes.size(); x++)
if(mToggledMeshes[x] == node)
return true;
return false;
}
ConsoleMethod( ShapeBase, updateMeshes, void, 2, 2, "() sets HideMesh mask for network updates")
{
if(!object->isServerObject()) return;
object->setMaskBits(ShapeBase::HideMeshMask);
}
void ShapeBase::MeshToggleOffAll()
{
mToggledMeshes.clear();
}
void ShapeBase::MeshToggleOnAll()
{
S32 i;
TSShape const* mShape = getShape();
mToggledMeshes.clear();
for (i=0; i< mShape->objects.size(); i++)
{
if (mShape->objects[i].nameIndex>=0)
mToggledMeshes.push_back(mShape->objects[i].nameIndex);
}
}
void ShapeBase::MeshOffAll()
{
if(!mDataBlock->invertHiddenMeshes)
MeshToggleOnAll();
else
MeshToggleOffAll();
}
ConsoleMethod( ShapeBase, MeshOffAll, void, 2, 2, "() Hide all meshes")
{
if(!object->isServerObject()) return;
object->MeshOffAll();
}
void ShapeBase::MeshOnAll()
{
if(!mDataBlock->invertHiddenMeshes)
MeshToggleOffAll();
else
MeshToggleOnAll();
}
ConsoleMethod( ShapeBase, MeshOnAll, void, 2, 2, "() Show all meshes")
{
if(!object->isServerObject()) return;
object->MeshOnAll();
}
void ShapeBase::MeshClearFromToggled(const char * meshName)
{
TSShape const* mShape = getShape();
for(S32 x = 0; x < mToggledMeshes.size(); x++)
{
if (dStricmp(meshName, mShape->getName(mToggledMeshes[x])) == 0)
{
mToggledMeshes.erase(x);
return;
}
}
}
void ShapeBase::MeshAddToToggled(const char * meshName)
{
TSShape const* mShape = getShape();
for (S32 i=0; i< mShape->objects.size(); i++)
{
S32 nameIndex = mShape->objects[i].nameIndex;
if (nameIndex>=0)
{
if (dStricmp(meshName, mShape->getName(nameIndex)) == 0)
{
for(int x = 0; x < mToggledMeshes.size(); x++)
{
if(mToggledMeshes[x] == nameIndex)
return;
}
mToggledMeshes.push_back(nameIndex);
return;
}
}
}
}
void ShapeBase::MeshOff(const char * meshName)
{
if (meshName == '\0')
{
Con::errorf("MeshOff(): Unable to toggle visibility for mesh %s.", meshName);
return;
}
if(!mDataBlock->invertHiddenMeshes)
MeshAddToToggled(meshName);
else
MeshClearFromToggled(meshName);
}
ConsoleMethod( ShapeBase, MeshOff, void, 3, 3, "(string meshname)")
{
if(!object->isServerObject()) return;
object->MeshOff(argv[2]);
}
void ShapeBase::MeshOn(const char * meshName)
{
if (meshName == '\0') return;
if(!mDataBlock->invertHiddenMeshes)
MeshClearFromToggled(meshName);
else
MeshAddToToggled(meshName);
}
ConsoleMethod( ShapeBase, MeshOn, void, 3, 3, "(string meshname)")
{
if(!object->isServerObject()) return;
object->MeshOn(argv[2]);
}
// Some development-handy functions
#ifndef TORQUE_SHIPPING
void ShapeBase::MeshListToggled()
{
for (int i=0; i<mShapeInstance->getShape()->objects.size(); i++)
{
const char * skinName = "";
S32 nameIndex = mShapeInstance->getShape()->objects[i].nameIndex;
if (nameIndex>=0 && (isMeshToggled(nameIndex)))
{
skinName = mShapeInstance->getShape()->getName(nameIndex);
Con::errorf("nameIndex %3d: %s ", nameIndex, skinName);
}
}
}
void ShapeBase::MeshListNonToggled()
{
for (int i=0; i<mShapeInstance->getShape()->objects.size(); i++)
{
const char * skinName = "";
S32 nameIndex = mShapeInstance->getShape()->objects[i].nameIndex;
if (nameIndex>=0 && (!isMeshToggled(nameIndex)))
{
skinName = mShapeInstance->getShape()->getName(nameIndex);
Con::errorf("nameIndex %3d: %s ", nameIndex, skinName);
}
}
}
void ShapeBase::MeshOffList()
{
if(!mDataBlock->invertHiddenMeshes)
MeshListToggled();
else
MeshListNonToggled();
}
ConsoleMethod( ShapeBase, MeshOffList, void, 2, 2, "() List all not visible meshes")
{
object->MeshOffList();
}
void ShapeBase::MeshOnList()
{
if(!mDataBlock->invertHiddenMeshes)
MeshListNonToggled();
else
MeshListToggled();
}
ConsoleMethod( ShapeBase, MeshOnList, void, 2, 2, "List all visible meshes")
{
object->MeshOnList();
}
void ShapeBase::ModelDump()
{
//A little bit of test info on the layout of the model
FileStream st;
#if (defined TORQUE_APP_VERSION) && (TORQUE_APP_VERSION>=1800)
if(gResourceManager->openFileForWrite(st, "Model.dump"))
#else
st.open("Model.dump", FileStream::ReadWrite);
if ((st.getStatus() == Stream::Ok) || (st.getStatus() == Stream::EOS))
#endif
if (mShapeInstance)
mShapeInstance->dump(st);
else
Con::errorf("No shapeinstance");
else
Con::errorf("Error opening dump file");
}
ConsoleMethod( ShapeBase, ModelDump, void, 2, 2, "() Dump known info on a model")
{
object->ModelDump();
}
#endif // #ifndef TORQUE_SHIPPING
const char * ShapeBase::getMeshList(bool vis)
{
if (mDataBlock->invertHiddenMeshes) vis = !vis;
char *ret = Con::getReturnBuffer(2048);
ret[0] = '\0';
for (int i=0; i<mShapeInstance->getShape()->objects.size(); i++)
{
const char * skinName = "";
S32 nameIndex = mShapeInstance->getShape()->objects[i].nameIndex;
// Some boolean logic play
if (nameIndex>=0 && ( (!vis && isMeshToggled(nameIndex)) || (vis && !isMeshToggled(nameIndex)) ))
{
skinName = mShapeInstance->getShape()->getName(nameIndex);
dSprintf(ret, 2048, "%s %s", ret, skinName);
//Con::errorf("nameIndex %3d: %s ", nameIndex, skinName);
}
}
return ret;
}
ConsoleMethod( ShapeBase, getMeshList, const char *, 3, 3, "(bool onlyVisibles) Get a list of meshes")
{
return object->getMeshList(dAtob(argv[2]));
}
//--------------------------------------------------------------------------
// End of HideMesh v2 Part
//--------------------------------------------------------------------------
#endif------------------------------------------------------Notice 3:
This is network-safe implementation, but in case you catch anything strange - please share with the community, fixes and improvements are welcomed!
About the author
Game developer.
#2
So, you keep visible only 5 meshes for example, and you have 15 "hidden", in previous resource it will transmit the list of "hidden" meshes, in this one - if you set invertHiddenMeshes to true on datablock, it will transmit only "visible" meshes - so we gain 3 times less data to transmit (5 vs 15). More meshes in a model - more benefits.
I don't say it's completely new or much different, it's improved from original with all fixes applied "all-in-one". Credits go to the original resource creator as stated at the top of this page.
09/24/2008 (7:07 am)
from Notice 2 part:Quote:This means if you have a model with lots of meshes (like few types of clothing, few armor types) - the amount could easily get up high (even 20 is already high).
This implementation is a bit different from original - the main thing is:
(quote from comments of original resource - by Orion Elenzil)
[quote]
If you're going to have mostly hidden meshes with only a few visible ones...
[quote]
You can set it via datablock:
%datablock.invertHiddenMeshes = true;This doesn't affect the scripting, you still do MeshOn() to make mesh visible. All the stuff is handled via engine for network saving.
You will need to set to true in case you have most of meshes invisible with only "some" visible. Otherwise keep it "false" (default).
So, you keep visible only 5 meshes for example, and you have 15 "hidden", in previous resource it will transmit the list of "hidden" meshes, in this one - if you set invertHiddenMeshes to true on datablock, it will transmit only "visible" meshes - so we gain 3 times less data to transmit (5 vs 15). More meshes in a model - more benefits.
I don't say it's completely new or much different, it's improved from original with all fixes applied "all-in-one". Credits go to the original resource creator as stated at the top of this page.
#3
09/24/2008 (8:41 am)
Nice implementation. The only addition I might have suggested is the ability to hide/show more than one mesh per call, but your use of updatemeshes() makes that completely unnecessary!
#4
09/24/2008 (8:51 am)
I choose using this route over the multi-mesh toggling because with current way it's easier to work with it in loops, like:for(%i=0;%i<%meshCount;%i++)
{
if (%condition)
%obj.meshOn(%meshes[%i]);
else
%obj.meshOff(%meshes[%i]);
}
%obj.updateMeshes();
#5
09/24/2008 (8:56 am)
Yes, it's a pretty elegant solution really. Have you tested it with new clients joining?
#6
without worrying about if it is new or old client.
Why? When the new player connects, server sets netMask to include everything by default, so it gets the list correctly together with everything else.
09/24/2008 (9:09 am)
Yes, it's working for both, as it transmits whole VectorWhy? When the new player connects, server sets netMask to include everything by default, so it gets the list correctly together with everything else.
#7
For example, you could have a model with: Legs_Nude, Legs_Jeans, Legs_Armor. If you wanted to turn on Legs_Armor and disable any other legs (regardless of what they are) you would do:
Using this function, so long as your art assets share a common naming convention, you can replace specific parts without having to be aware of what part is currently visible.
With a little extra work effort on naming your meshes you can allow similar overlapping pieces as well.
For example, we name all armor or clothes parts with _A_ and all nude parts without. So LArm_0000 would be a bare left arm, but LArm_A_0000 would be some particular clothing or armor piece. We could then do:
This would only hide meshes that start with LAarm_A_ leaving the nude arm (LArm_0000) visible, and allowing the new arm armor to appear in conjunction with the nude arm.
09/24/2008 (12:51 pm)
Nice work. This is very similar to a solution that I use based off of the original resource (storing a list of visible meshes rather than hidden meshes, manually calling an Update function, etc.). I don't have the engine code in front of me right now, but another function that I found to be very useful is what I call MeshOffSimilar. It basically just does a string comparison against each mesh piece in the visible list against a string you provide and if there's a match, it hides that mesh.For example, you could have a model with: Legs_Nude, Legs_Jeans, Legs_Armor. If you wanted to turn on Legs_Armor and disable any other legs (regardless of what they are) you would do:
%obj.MeshOffSimilar("Legs_");
%obj.MeshOn("Legs_Armor");Using this function, so long as your art assets share a common naming convention, you can replace specific parts without having to be aware of what part is currently visible.
With a little extra work effort on naming your meshes you can allow similar overlapping pieces as well.
For example, we name all armor or clothes parts with _A_ and all nude parts without. So LArm_0000 would be a bare left arm, but LArm_A_0000 would be some particular clothing or armor piece. We could then do:
%obj.MeshOffSimilar("LArm_A_");
%obj.MeshOn("LArm_A_0002");This would only hide meshes that start with LAarm_A_ leaving the nude arm (LArm_0000) visible, and allowing the new arm armor to appear in conjunction with the nude arm.
#8
09/24/2008 (2:40 pm)
nice.
#9
Sid.
09/24/2008 (6:35 pm)
Sweet stuff guys I know many people will be using this maybe even myself when I get to that extent in my gaming making process, but for now I'm just working on the 3d modeling part learning blender 3d (a free 3d modeling program that's not half bad and has a decent exporter for tgea thanks to Joseph and the guys). Learning how to make them so then I can implement stuff like armor via your nice code here perhaps =). Thanks again and please keep this stuff rollin if we all help each other out enough perhaps we'll all reach our dream goal of creating content or a game ;).Sid.
#10
One question (which I will admit I already asked on the previous resource) is how can I find out the which mesh has been hit by a projectile? For example, if I want to lose a particular piece of armour if it is hit?
If you have any ideas they'd be hugely appreciated!
Thanks.
09/26/2008 (3:38 pm)
Nice work - I only got around to using the previous hidden meshes resource a couple of weeks ago. We will have a whole bunch of hidden meshes so I'll definately be updating the code to this version.One question (which I will admit I already asked on the previous resource) is how can I find out the which mesh has been hit by a projectile? For example, if I want to lose a particular piece of armour if it is hit?
If you have any ideas they'd be hugely appreciated!
Thanks.
#11
Where do i call the meshon console functions from (tgea 1.7.1). Also since i havent setup my mesh in any special way (just a single mesh with texture) do i need to set it up any different from a standard torque model? Is there a specific naming scheme i need e.t.c?
09/27/2008 (8:26 am)
Thanks for this resource, I have a quick question since its not totally clear for me. I just implemented this and get a crash on map load, i assume its because i need to call meshonall in script somewhere?Where do i call the meshon console functions from (tgea 1.7.1). Also since i havent setup my mesh in any special way (just a single mesh with texture) do i need to set it up any different from a standard torque model? Is there a specific naming scheme i need e.t.c?
#12
09/27/2008 (4:59 pm)
Nice additions sez the original author
#13
10/08/2008 (2:30 pm)
@Everyone with regards to Ian's question: I fixed it for him, so no worries :)
#14
10/13/2008 (6:28 am)
How did you fix it for him? Some in sight would be great :)
#15
10/13/2008 (10:59 pm)
@Andrew: He missed some source changes. After that was fixed, everything ran fine.
#16
10/18/2008 (5:17 am)
Nice improved code, i like the ifdefs, i usually use ifdefs when adding resources. Works without any changes in TGE ;)
#17
Not sure if it's been brought up before or not.
Now as I remember it there's a cap of 10k vectors for an model, correct me if I'm wrong.
Now the question is has anyone thought about using mounting points for certain ideas of clothing (caps, hats, coats, etc...) to keep below the 10k limit? I'm wonder if we used the hidden meshes on hats and caps we could in effect have one hat/helmet model which attaches to the head and then change it to a different hidden mesh for changes( eg. helmets with visors, zoom scopers, facemasks, etc...), and even the same sort of idea for caps and coats with hoods and scrafes.
Just wondering a I'm looking at options to allow for characters to have caps and coats that have effects/enodes attached to them, so if worn by character and character does an enode that items adds to the effect of the enode/animation (eg.. Character runs and then jumps off a ledge, the cap opens up behind character as he/she runs and then when jumping it bollons out till character lands, etc...)
11/14/2008 (5:02 pm)
Now I've got a question for you all about the Hiden Meshes!Not sure if it's been brought up before or not.
Now as I remember it there's a cap of 10k vectors for an model, correct me if I'm wrong.
Now the question is has anyone thought about using mounting points for certain ideas of clothing (caps, hats, coats, etc...) to keep below the 10k limit? I'm wonder if we used the hidden meshes on hats and caps we could in effect have one hat/helmet model which attaches to the head and then change it to a different hidden mesh for changes( eg. helmets with visors, zoom scopers, facemasks, etc...), and even the same sort of idea for caps and coats with hoods and scrafes.
Just wondering a I'm looking at options to allow for characters to have caps and coats that have effects/enodes attached to them, so if worn by character and character does an enode that items adds to the effect of the enode/animation (eg.. Character runs and then jumps off a ledge, the cap opens up behind character as he/she runs and then when jumping it bollons out till character lands, etc...)
#18
11/14/2008 (6:51 pm)
pierre, i think the limit on the number of vertices in a ShapeBase mesh is either much higher than 10,000, or doesn't exist at all. you might run into trouble with some of the intermediate tools in the export process, but again, if you do it will be well past 10,000 vertices. i would recommend solving that building that bridge when you need it. don't forget also you can use texture swapping in concert with mesh hiding to massively increase the amount of variation in your characters.
#19
I know about texture swapping, from mod addons I've made for OFP and ArmA. Also included proxies for extra model features, which was the idea behind my post.
11/14/2008 (11:56 pm)
Ok, I'll see how far I can push the vertices with hidden meshes. I know about texture swapping, from mod addons I've made for OFP and ArmA. Also included proxies for extra model features, which was the idea behind my post.
#20
11/15/2008 (4:00 am)
Excellent! I was about to re-implement the original resource and make my changes, but you fixed all the issues I had :) 
Torque 3D Owner Michael Chew