T3D 1.1 beta 3 - TSShapeConstructor and Shape Editor Detail Nodes System rendering failure w/fix - FIXED
by Steve Acaster · in Torque 3D Professional · 09/24/2010 (1:07 am) · 11 replies
T3D 1.1 Beta 3
Win7
Target:
TSShapeConstructor -> Shape Editor -> detail nodes system
Issue:
TSShapeConstructor has some baffling issues in beta 3 relating to detail nodes. First up, this affects importing older scripts for meshes or making new ones with the Shape Editor.
All The detail/LOD Meshes using a TSShapeConstructor script fail to render.
If you select a mesh/object in Shape Editor it will render, if you go back to the world editor you can now see that mesh/object. If you go into Shape Editor again and select another TsShapeConstructor object this one will now render, go back to World Editor and it still renders, but now the previous mesh/object is no longer rendering again.
Quit, restart, load up, and once again no shapes using TsShapeConstructor will render.
To Repeat:
Have 4 meshes.
Select one and go into Shape Editor.
Attach a new mesh to a new detail node using properties->detail->import shape into->new detail. Save it and check that the script file looks kinda like this.
Now make another object the same way, save your level with these 2 objects in and quit.
Restart T3D. Load up your mission. See that neither object renders. Go into Shape Editor and select one object, see it render. Go into World Editor/Play game and still see it render in world. Go back to shape editor, select other object, see first object disappear now new object is rendering in game.
Quit T3D, reload up, see nothing made with TSShapeConstructor rendering.
Suggest:
As this wasn't an issue previously, unembuggerate whatever got busticated.
[edit]10Dec2010
Fix below but I'm not a programmer so can't say if this is the best way .... but at least it works
Made worse in 1.1 Preview as it now crashes - linky but now fixed there too!
Win7
Target:
TSShapeConstructor -> Shape Editor -> detail nodes system
Issue:
TSShapeConstructor has some baffling issues in beta 3 relating to detail nodes. First up, this affects importing older scripts for meshes or making new ones with the Shape Editor.
All The detail/LOD Meshes using a TSShapeConstructor script fail to render.
If you select a mesh/object in Shape Editor it will render, if you go back to the world editor you can now see that mesh/object. If you go into Shape Editor again and select another TsShapeConstructor object this one will now render, go back to World Editor and it still renders, but now the previous mesh/object is no longer rendering again.
Quit, restart, load up, and once again no shapes using TsShapeConstructor will render.
To Repeat:
Have 4 meshes.
Select one and go into Shape Editor.
Attach a new mesh to a new detail node using properties->detail->import shape into->new detail. Save it and check that the script file looks kinda like this.
singleton TSShapeConstructor(LMA_chapel_intDae)
{
baseShape = "./LMA_chapel_int.dae";
};
function LMA_chapel_intDae::onLoad(%this)
{
%this.addMesh("dummychapelint 3", "art/shapes/chapel/Module_Chapel/dummy_chapel_int.dts", "dummychapelint 2");
%this.setDetailLevelSize("2", "500");
}You don't have to resize the detail level if you don't want, it's not going to affect the outcome.Now make another object the same way, save your level with these 2 objects in and quit.
Restart T3D. Load up your mission. See that neither object renders. Go into Shape Editor and select one object, see it render. Go into World Editor/Play game and still see it render in world. Go back to shape editor, select other object, see first object disappear now new object is rendering in game.
Quit T3D, reload up, see nothing made with TSShapeConstructor rendering.
Suggest:
As this wasn't an issue previously, unembuggerate whatever got busticated.
[edit]10Dec2010
Fix below but I'm not a programmer so can't say if this is the best way .... but at least it works
Made worse in 1.1 Preview as it now crashes - linky but now fixed there too!
About the author
One Bloke ... In His Bedroom ... Making Indie Games ...
#2
In debug I get assertion errors regarding tsShape.cpp (141) TsShape::getname followed by an out of bounds, when selecting an object and attempting to go into shape editor, and then this stack.
09/24/2010 (4:07 pm)
I also seem to get a few crashes when selecting different TsShapeConstructor objects in Shape Editor.In debug I get assertion errors regarding tsShape.cpp (141) TsShape::getname followed by an out of bounds, when selecting an object and attempting to go into shape editor, and then this stack.
> Yorks_DEBUG.dll!dStrlen(const char * str=0xfdfdfe1a) Line 70 + 0x12 bytes C++ Yorks_DEBUG.dll!StringStack::setStringValue(const char * s=0xfdfdfe1a) Line 147 + 0x9 bytes C++ Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=25621, const char * functionName=0x08e0f8ec, Namespace * thisNamespace=0x086088dc, unsigned int argc=1, const char * * argv=0x11daeea0, bool noCalls=false, const char * packageName=0x00000000, int setFrame=-1) Line 1639 C++ Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=2126, const char * functionName=0x08e0ddc8, Namespace * thisNamespace=0x08608df0, unsigned int argc=3, const char * * argv=0x11daeea0, bool noCalls=false, const char * packageName=0x00000000, int setFrame=-1) Line 1604 + 0x41 bytes C++ Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=14, const char * functionName=0x00000000, Namespace * thisNamespace=0x00000000, unsigned int argc=0, const char * * argv=0x00000000, bool noCalls=false, const char * packageName=0x00000000, int setFrame=0) Line 1604 + 0x41 bytes C++ Yorks_DEBUG.dll!CodeBlock::compileExec(const char * fileName=0x00000000, const char * inString=0x01655def, bool noCalls=false, int setFrame=0) Line 648 C++ Yorks_DEBUG.dll!Con::evaluate(const char * string=0x01655def, bool echo=false, const char * fileName=0x00000000) Line 990 C++ Yorks_DEBUG.dll!cf_eval(SimObject * __formal=0x081ff720, int argc=2, const char * * argv=0x11daeea0) Line 2116 + 0x10 bytes C++ Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=10846, const char * functionName=0x081adad8, Namespace * thisNamespace=0x0809ebd0, unsigned int argc=3, const char * * argv=0x11daeea0, bool noCalls=false, const char * packageName=0x00000000, int setFrame=-1) Line 1635 + 0x20 bytes C++ Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=1841, const char * functionName=0x02cc2258, Namespace * thisNamespace=0x08608a14, unsigned int argc=2, const char * * argv=0x11daeea0, bool noCalls=false, const char * packageName=0x00000000, int setFrame=-1) Line 1604 + 0x41 bytes C++ Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=2215, const char * functionName=0x11968f9c, Namespace * thisNamespace=0x08608a48, unsigned int argc=2, const char * * argv=0x0012aad0, bool noCalls=false, const char * packageName=0x00000000, int setFrame=-1) Line 1604 + 0x41 bytes C++ Yorks_DEBUG.dll!Namespace::Entry::execute(int argc=3, const char * * argv=0x0012aad0, ExprEvalState * state=0x11db6460) Line 1236 + 0x31 bytes C++ Yorks_DEBUG.dll!Con::execute(SimObject * object=0x08f238a8, int argc=3, const char * * argv=0x0012aad0, bool thisCallOnly=false) Line 1076 + 0x15 bytes C++ Yorks_DEBUG.dll!Con::_executef(SimObject * obj=0x08f238a8, int checkArgc=2, int argc=2, const char * a=0x11968f9c, const char * b=0x01655730, const char * c=0x00000000, const char * d=0x00000000, const char * e=0x00000000, const char * f=0x00000000, const char * g=0x00000000, const char * h=0x00000000, const char * i=0x00000000, const char * j=0x00000000, const char * k=0x00000000) Line 1111 + 0x16 bytes C++ Yorks_DEBUG.dll!Con::executef(SimObject * obj=0x08f238a8, const char * a=0x11968f9c, const char * b=0x01655730) Line 1117 + 0x30 bytes C++ Yorks_DEBUG.dll!GuiTreeViewCtrl::onItemSelected(GuiTreeViewCtrl::Item * item=0x197baf98) Line 1997 + 0x27 bytes C++ Yorks_DEBUG.dll!GuiTreeViewCtrl::setItemSelected(int itemId=9729, bool select=true) Line 2122 C++ Yorks_DEBUG.dll!cm_GuiTreeViewCtrl_selectItem(GuiTreeViewCtrl * object=0x08f238a8, int argc=3, const char * * argv=0x11daeea0) Line 4521 C++ Yorks_DEBUG.dll!cm_GuiTreeViewCtrl_selectItem_caster(SimObject * object=0x08f238a8, int argc=3, const char * * argv=0x11daeea0) Line 4513 + 0x65 bytes C++ Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=1634, const char * functionName=0x08377a50, Namespace * thisNamespace=0x08608394, unsigned int argc=1, const char * * argv=0x11daeea0, bool noCalls=false, const char * packageName=0x00000000, int setFrame=-1) Line 1697 + 0x20 bytes C++
#3
09/24/2010 (4:09 pm)
add the rest of that one ... when the forums will let me post against it's flood detection ...Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=2761, const char * functionName=0x0833ff88, Namespace * thisNamespace=0x081f0f10, unsigned int argc=2, const char * * argv=0x11daeea0, bool noCalls=false, const char * packageName=0x00000000, int setFrame=-1) Line 1604 + 0x41 bytes C++
Yorks_DEBUG.dll!CodeBlock::exec(unsigned int ip=11, const char * functionName=0x00000000, Namespace * thisNamespace=0x00000000, unsigned int argc=0, const char * * argv=0x00000000, bool noCalls=false, const char * packageName=0x00000000, int setFrame=-1) Line 1604 + 0x41 bytes C++
Yorks_DEBUG.dll!CodeBlock::compileExec(const char * fileName=0x00000000, const char * inString=0x193e4c0d, bool noCalls=false, int setFrame=0) Line 648 C++
Yorks_DEBUG.dll!Con::evaluate(const char * string=0x193e4c0d, bool echo=false, const char * fileName=0x00000000) Line 990 C++
Yorks_DEBUG.dll!GuiControl::evaluate(const char * str=0x193e4c0d) Line 2392 + 0xd bytes C++
Yorks_DEBUG.dll!GuiControl::execConsoleCallback() Line 2403 + 0x17 bytes C++
Yorks_DEBUG.dll!GuiControl::onAction() Line 1157 C++
Yorks_DEBUG.dll!GuiButtonBaseCtrl::onAction() Line 437 C++
Yorks_DEBUG.dll!GuiBitmapButtonCtrl::onAction() Line 402 C++
Yorks_DEBUG.dll!GuiButtonBaseCtrl::onMouseUp(const GuiEvent & event={...}) Line 316 C++
Yorks_DEBUG.dll!GuiCanvas::rootMouseUp(const GuiEvent & event={...}) Line 1049 C++
Yorks_DEBUG.dll!GuiCanvas::processMouseEvent(InputEventInfo & inputEvent={...}) Line 743 C++
Yorks_DEBUG.dll!GuiCanvas::processInputEvent(InputEventInfo & inputEvent={...}) Line 516 + 0x1e bytes C++
Yorks_DEBUG.dll!WindowInputGenerator::generateInputEvent(InputEventInfo & inputEvent={...}) Line 75 + 0x16 bytes C++
Yorks_DEBUG.dll!WindowInputGenerator::handleMouseButton(unsigned int did=0, unsigned int modifiers=0, unsigned int action=2, unsigned short button=0) Line 198 C++
Yorks_DEBUG.dll!fastdelegate::FastDelegate4<unsigned int,unsigned int,unsigned int,unsigned short,void>::operator()(unsigned int p1=0, unsigned int p2=0, unsigned int p3=2, unsigned short p4=0) Line 1245 + 0x27 bytes C++
Yorks_DEBUG.dll!Signal<void __cdecl(unsigned int,unsigned int,unsigned int,unsigned short)>::trigger(unsigned int a=0, unsigned int b=0, unsigned int c=2, unsigned short d=0) Line 435 C++
Yorks_DEBUG.dll!Journal::Call<Signal<void __cdecl(unsigned int,unsigned int,unsigned int,unsigned short)>,unsigned int,unsigned int,unsigned int,unsigned short>(Signal<void __cdecl(unsigned int,unsigned int,unsigned int,unsigned short)> * obj=0x05422d00, void (unsigned int, unsigned int, unsigned int, unsigned short)* method=0x107c998b, unsigned int a=0, unsigned int b=0, unsigned int c=2, unsigned short d=0) Line 536 + 0xc1 bytes C++
Yorks_DEBUG.dll!JournaledSignal<void __cdecl(unsigned int,unsigned int,unsigned int,unsigned short)>::trigger(unsigned int a=0, unsigned int b=0, unsigned int c=2, unsigned short d=0) Line 133 + 0x1f bytes C++
Yorks_DEBUG.dll!_dispatch(HWND__ * hWnd=0x00030618, unsigned int message=514, unsigned int wParam=0, unsigned int lParam=2818460) Line 295 C++
Yorks_DEBUG.dll!DispatchNext() Line 569 + 0x15 bytes C++
Yorks_DEBUG.dll!Win32WindowManager::_process() Line 294 + 0x5 bytes C++
Yorks_DEBUG.dll!fastdelegate::FastDelegate0<void>::operator()() Line 905 + 0x16 bytes C++
Yorks_DEBUG.dll!Signal<void __cdecl(void)>::trigger() Line 375 C++
Yorks_DEBUG.dll!Process::processEvents() Line 78 C++
Yorks_DEBUG.dll!StandardMainLoop::doMainLoop() Line 570 + 0x5 bytes C++
Yorks_DEBUG.dll!torque_enginetick() Line 103 + 0x5 bytes C++
Yorks_DEBUG.dll!TorqueMain(int argc=2, const char * * argv=0x01744218) Line 370 + 0x5 bytes C++
Yorks_DEBUG.dll!torque_winmain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * __formal=0x00000000, char * lpszCmdLine=0x00273401, HINSTANCE__ * __formal=0x00000000) Line 424 + 0x17 bytes C++
Yorks_DEBUG.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpszCmdLine=0x00273401, int nCommandShow=1) Line 47 + 0x16 bytes C++
Yorks_DEBUG.exe!__tmainCRTStartup() Line 263 + 0x2c bytes C
Yorks_DEBUG.exe!WinMainCRTStartup() Line 182 C
kernel32.dll!75b91194()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
ntdll.dll!7710b495()
ntdll.dll!7710b468()
#4
Deleting meshes/nodes in the shape editor doesn't always seem to update or change the script file at all ... but after a bit of practise, this doesn't seem consistent, happening only on some object/cs files.
09/24/2010 (4:18 pm)
Also it doesn't look like it's deleting/overwriting the TsShapeCOnstructor info correctly, and thus you can end up with multiple "singleton TSShapeConstructor"s which are probably causing some issues.Deleting meshes/nodes in the shape editor doesn't always seem to update or change the script file at all ... but after a bit of practise, this doesn't seem consistent, happening only on some object/cs files.
#5
By replacing those files with the previous versions (non-programmer remember, I can read it, but that don't mean I can locate the particular problem) and doing an incremental build in VS2008, I can get the ShapeEditor based scripted LODs functioning/rendering correctly.
10/08/2010 (4:26 pm)
I'm thinking that the issue is the new LOD lookup table (amongst other things) in tsShapeInstance.cpp/h and tsShapeEdit.cpp.By replacing those files with the previous versions (non-programmer remember, I can read it, but that don't mean I can locate the particular problem) and doing an incremental build in VS2008, I can get the ShapeEditor based scripted LODs functioning/rendering correctly.
#6
10/29/2010 (6:15 pm)
Just to point out I'm using some lightmapped meshes - but I don't think that that's an issue. Have more than 2 script organized detailed objects ingame and they don't render.
#7
source/ts/tsShapeEdit.cpp
bool TSShape::addMesh ... at the end, change it to this.
12/10/2010 (6:51 pm)
Not a programmer so not sure this is the best fix but it works as desired ...source/ts/tsShapeEdit.cpp
//replace function
void TSShape::updateSmallestVisibleDL()
{
// Update smallest visible detail
mSmallestVisibleDL = -1;
mSmallestVisibleSize = F32_MAX;
for (S32 i = 0; i < details.size(); i++)
{
if ((details[i].size >= 0) && (details[i].size < mSmallestVisibleSize))
{
mSmallestVisibleDL = i;
mSmallestVisibleSize = details[i].size;
}
}bool TSShape::addMesh ... at the end, change it to this.
// Copy materials used by the source mesh (only if from a different shape)
if (srcShape != this)
{
for (S32 i = 0; i < mesh->primitives.size(); i++)
{
if (!(mesh->primitives[i].matIndex & TSDrawPrimitive::NoMaterial))
{
S32 drawType = (mesh->primitives[i].matIndex & (~TSDrawPrimitive::MaterialMask));
S32 MatIndex = mesh->primitives[i].matIndex & TSDrawPrimitive::MaterialMask;
const String& matName = srcShape->materialList->getMaterialName(MatIndex);
mesh->primitives[i].matIndex = drawType | materialList->size();
materialList->push_back(matName, srcShape->materialList->getFlags(MatIndex));
}
}
}
return true;
}
#8
code doesn't appear to have character count issues on website bug ... or it's been fixed whilst I was typing ...
12/10/2010 (6:58 pm)
edit:code doesn't appear to have character count issues on website bug ... or it's been fixed whilst I was typing ...
#9
Change TSShapeInstance::setCurrentDetail
12/10/2010 (7:02 pm)
source/ts/tsShapeInstance.cppChange TSShapeInstance::setCurrentDetail
void TSShapeInstance::setCurrentDetail( S32 dl, F32 intraDL )
{
PROFILE_SCOPE( TSShapeInstance_setCurrentDetail );
mCurrentDetailLevel = mClamp( dl, -1, mShape->mSmallestVisibleDL );
mCurrentIntraDetailLevel = intraDL > 1.0f ? 1.0f : (intraDL < 0.0f ? 0.0f : intraDL);
// restrict chosen detail level by cutoff value
S32 cutoff = getMin( smNumSkipRenderDetails, mShape->mSmallestVisibleDL );
if ( mCurrentDetailLevel>=0 && mCurrentDetailLevel<cutoff)
{
mCurrentDetailLevel = cutoff;
mCurrentIntraDetailLevel = 1.0f;
}
}
#10
add this function below
12/10/2010 (7:04 pm)
change TSShapeInstance::setDetailFromDistanceS32 TSShapeInstance::setDetailFromDistance( const SceneState *state, F32 scaledDistance )
{
PROFILE_SCOPE( TSShapeInstance_setDetailFromDistance );
// For debugging/metrics.
smLastScaledDistance = scaledDistance;
// Shortcut if the distance is really close or negative.
if ( scaledDistance <= 0.0f )
{
mCurrentDetailLevel = getMin( 1, mShape->details.size() ) - 1;
mCurrentIntraDetailLevel = 0.0f;
return mCurrentDetailLevel;
}
// The pixel scale is used the linearly scale the lod
// selection based on the viewport size.
//
// The original calculation from TGEA was...
//
// pixelScale = viewport.extent.x * 1.6f / 640.0f;
//
// Since we now work on the viewport height, assuming
// 4:3 aspect ratio, we've changed the reference value
// to 300 to be more compatible with legacy shapes.
//
const F32 pixelScale = state->getViewportExtent().y / 300.0f;
// This is legacy DTS support for older "multires" based
// meshes. The original crossbow weapon uses this.
//
// If we have more than one detail level and the maxError
// is non-negative then we do some sort of screen error
// metric for detail selection.
//
if ( mShape->mSmallestVisibleDL >= 0 &&
mShape->details.first().maxError >= 0 )
{
// The pixel size of 1 meter at the input distance.
F32 pixelRadius = state->projectRadius( scaledDistance, 1.0f ) * pixelScale;
static const F32 smScreenError = 5.0f;
return setDetailFromScreenError( smScreenError / pixelRadius );
}
F32 pixelRadius = state->projectRadius( scaledDistance, mShape->radius ) * pixelScale;
F32 adjustedPR = pixelRadius * smDetailAdjust;
if ( adjustedPR > smSmallestVisiblePixelSize &&
adjustedPR <= mShape->mSmallestVisibleSize )
adjustedPR = mShape->mSmallestVisibleSize + 0.01f;
return setDetailFromPixelSize( adjustedPR );
}add this function below
S32 TSShapeInstance::setDetailFromPixelSize( F32 pixelSize )
{
PROFILE_SCOPE( TSShapeInstance_setDetailFromPixelSize );
// For debugging/metrics.
smLastPixelSize = pixelSize;
// check to see if not visible first...
if ( pixelSize <= mShape->mSmallestVisibleSize )
{
// don't render...
mCurrentDetailLevel=-1;
mCurrentIntraDetailLevel = 0.0f;
return -1;
}
const Vector<TSShape::Detail> &details = mShape->details;
// same detail level as last time?
// only search for detail level if the current one isn't the right one already
if ( mCurrentDetailLevel < 0 ||
(mCurrentDetailLevel == 0 && pixelSize <= details[0].size) ||
(mCurrentDetailLevel>0 && (pixelSize <= details[mCurrentDetailLevel].size ||
pixelSize > details[mCurrentDetailLevel-1].size) ) )
{
PROFILE_SCOPE( TSShapeInstance_setDetailFromPixelSize_detailLoop );
// scan shape for highest detail size smaller than us...
// shapes details are sorted from largest to smallest...
// a detail of size <= 0 means it isn't a renderable detail level (utility detail)
for (S32 i=0; i<details.size(); i++)
{
if ( pixelSize > details[i].size )
{
mCurrentDetailLevel = i;
break;
}
if ( i + 1 >= details.size() || details[i+1].size < 0 )
{
// We've run out of details and haven't found anything?
// Let's just grab this one.
mCurrentDetailLevel = i;
break;
}
}
}
F32 curSize = details[mCurrentDetailLevel].size;
F32 nextSize = mCurrentDetailLevel == 0 ? 2.0f * curSize : details[mCurrentDetailLevel - 1].size;
setCurrentDetail( mCurrentDetailLevel,
nextSize-curSize>0.01f ? (pixelSize - curSize) / (nextSize - curSize) : 1.0f );
return mCurrentDetailLevel;
}
#11
Way down in a public declaration
12/10/2010 (7:08 pm)
Finally, in source/ts/tsShapeInstance.hWay down in a public declaration
/// Selects the current detail level using the scaled
/// distance between your object and the camera.
///
/// @see TSShape::Detail.
S32 setDetailFromDistance( const SceneState *state, F32 scaledDist );
/// Sets the current detail level using the legacy screen error metric.
S32 setDetailFromPixelSize( F32 pixelSize );//yorks add this <----
S32 setDetailFromScreenError( F32 errorTOL );
enum
{
Associate David Montgomery-Blake
David MontgomeryBlake