Updated GuiObjectView for TGEA 1.7.1 and 1.8.0
by Jaimi McEntire · 02/01/2009 (12:31 pm) · 26 comments
This is an updated GuiObjectView for TGEA versions 1.7.1 and 1.8.0. This includes new properties for lighting and interaction, and a bug fix.
Link: GuiObjectView Link
What's New:
Bug Fix: If the model is larger than 5 units, the Min and Max distance are automatically adjusted.
Bug Fix: SetSeq (SetObjectAnimation) was doing nothing. Thanks Mike!
New Properties:
Azimuth - The angle of the light around the Z axis (degrees)
Elevation - The Pitch of the light (degrees)
LightColor - The color of the light (ColorF)
Ambient - The ambient color (ColorF)
LockOrbit - Locks the orbit distance (bool)
OrbitDistance - The distance that the orbit distance is locked at (F32)
LockXRotation - Locks the rotation on the X axis (bool)
LockedXRotation - The value the X axis rotation is locked at (F32, Radians)
LockZRotation - Locks the rotation on the Z axis (bool)
LockedZRotation - The value that the Z Axis is locked at (F32, radians)
For example, If you only want the user to scroll around the object (instead of looking at the top and bottom):
MyObjectView.LockXRotation = true;
MyObjectView.LockedXRotation = 0;
Perhaps you want the lighting to be off center, to give a better shaded look:
MyObjectView.Azimuth = 190;
MyObjectView.Elevation = 45;
MyObjectView.Ambient = "0.3 0.3 0.3 1"; // Lower the ambient color
The zip file contains versions for both TGEA 1.7.1 and TGEA 1.8.0 in separate directories.
Still several things I plan to do:
1. Add support for multiple attachments (currently it's limited to 1)
2. Draw a shadow under the player to give a more 3D appearance
Update:
Added animation support thanks to Matt J. The zip file has been updated.
Link: GuiObjectView Link
What's New:
Bug Fix: If the model is larger than 5 units, the Min and Max distance are automatically adjusted.
Bug Fix: SetSeq (SetObjectAnimation) was doing nothing. Thanks Mike!
New Properties:
Azimuth - The angle of the light around the Z axis (degrees)
Elevation - The Pitch of the light (degrees)
LightColor - The color of the light (ColorF)
Ambient - The ambient color (ColorF)
LockOrbit - Locks the orbit distance (bool)
OrbitDistance - The distance that the orbit distance is locked at (F32)
LockXRotation - Locks the rotation on the X axis (bool)
LockedXRotation - The value the X axis rotation is locked at (F32, Radians)
LockZRotation - Locks the rotation on the Z axis (bool)
LockedZRotation - The value that the Z Axis is locked at (F32, radians)
For example, If you only want the user to scroll around the object (instead of looking at the top and bottom):
MyObjectView.LockXRotation = true;
MyObjectView.LockedXRotation = 0;
Perhaps you want the lighting to be off center, to give a better shaded look:
MyObjectView.Azimuth = 190;
MyObjectView.Elevation = 45;
MyObjectView.Ambient = "0.3 0.3 0.3 1"; // Lower the ambient color
The zip file contains versions for both TGEA 1.7.1 and TGEA 1.8.0 in separate directories.
Still several things I plan to do:
1. Add support for multiple attachments (currently it's limited to 1)
2. Draw a shadow under the player to give a more 3D appearance
Update:
Added animation support thanks to Matt J. The zip file has been updated.
About the author
Recent Blogs
• Replicator Updates for TGEA 1.8.1• GuiLensFlareHud - Lens flares and white out for TGEA 1.8.1
• fxGenericObject for TGEA 1.8.1
• GuiStatusCtrl - *Updated* Display Field Name, Values, Status Bar for any field or method on any named object. TGEA and (new! TGE 1.52)
• Bitmap Channel Embedder
#2
02/01/2009 (11:23 pm)
Thank you Jaimi, this is saving me many hours! You should start calling your resources Jems. :)
#3
I went ahead and re-added animation support, as my game requires it (it looks like it was in there at one time though).
For anyone interested, make the following changes to add animation support:
In guiObjectView.h, change
I also added an extra variable, 'thread':
Now, in GuiObjectView.cpp, replace
Now, at the bottom of GuiObjectView::setObjectModel, add this:
Finally, find (in GuiObjectView::renderWorld)
That's it for source changes.
Now, in your GUI script, in the OnWake function, add
02/02/2009 (6:58 pm)
Thanks for the resource.I went ahead and re-added animation support, as my game requires it (it looks like it was in there at one time though).
For anyone interested, make the following changes to add animation support:
In guiObjectView.h, change
class GuiObjectView : public GuiTSCtrlto
class GuiObjectView : public GuiTSCtrl, public virtual ITickableand add the following functions:
void setObjectAnimation(S32 index); void setObjectAnimationByName(const char* name); virtual void advanceTime( F32 timeDelta );
I also added an extra variable, 'thread':
TSThread * runThread,*thread; //add the second var
Now, in GuiObjectView.cpp, replace
void GuiObjectView::setObjectAnimation(S32 index)
{
if ((0 > index) || (index > MAX_ANIMATIONS))
{
Con::warnf(avar("GuiObjectView: The index %d is outside the permissible range. Please specify an animation index in the range [0, %d]", index, MAX_ANIMATIONS));
return;
}
mAnimationSeq = index;
}withvoid GuiObjectView::advanceTime( F32 timeDelta )
{
if(mModel)
mModel->advanceTime( timeDelta, thread );
}
void GuiObjectView::setObjectAnimationByName(const char* name)
{
if(mModel)
setObjectAnimation(mModel->getShape()->findSequence(name));
}
void GuiObjectView::setObjectAnimation(S32 index)
{
if ((0 > index) || (index > MAX_ANIMATIONS))
{
Con::warnf(avar("GuiObjectView: The index %d is outside the permissible range. Please specify an animation index in the range [0, %d]", index, MAX_ANIMATIONS));
return;
}
if(mModel)
{
mAnimationSeq = index;
if(thread)
mModel->setSequence(thread,mAnimationSeq,0);
}
}Now, at the bottom of GuiObjectView::setObjectModel, add this:
thread = mModel->addThread();
Finally, find (in GuiObjectView::renderWorld)
if (mModel)
{
// animate and render in a run pose
//F32 fdt = dt;
// mModel->advanceTime( fdt/1000.f, runThread );
// mModel->animate();
mModel->render();
}and uncomment mModel->animate(), so it looks like thisif (mModel)
{
// animate and render in a run pose
//F32 fdt = dt;
// mModel->advanceTime( fdt/1000.f, runThread );
mModel->animate();
mModel->render();
}That's it for source changes.
Now, in your GUI script, in the OnWake function, add
view.setSequence("idle");and of course replace view with whatever you named the objectview control, and idle with whatever animation you want.
#4
Also, I needed to add
#include "core/itickable.h" to guiobjectview.h
and added these stubs so that guiObjectView was not abstract:
virtual void interpolateTick( F32 delta ) {};
virtual void processTick() {};
02/02/2009 (7:58 pm)
Thanks for the update, Matt. I went ahead and added the code to the download above - I'll update the resource to show the new functionality. I did make a couple of changes mostly to do with using runThread instead of creating a new thread.Also, I needed to add
#include "core/itickable.h" to guiobjectview.h
and added these stubs so that guiObjectView was not abstract:
virtual void interpolateTick( F32 delta ) {};
virtual void processTick() {};
#5
I have afully working and fresh compiled version of the thing you posted here and I've been trying to set an animation using modelview.setSequence("player_forwardw.dsq");
I get this feedback, and no animation playing...
Is it just me or is anything broken ?
02/08/2009 (4:03 am)
Uhm guys; I know the rule -never post when tired, but...I have afully working and fresh compiled version of the thing you posted here and I've been trying to set an animation using modelview.setSequence("player_forwardw.dsq");
I get this feedback, and no animation playing...
scriptsAndAssets/client/scripts/createActorGui.cs (120): Unknown command setSequence. Object modelView(4576) modelView -> GuiObjectView -> GuiTSCtrl -> GuiContainer -> GuiControl -> SimGroup -> SimSet -> SimObject
Is it just me or is anything broken ?
#6
ConsoleMethod(GuiObjectView, setSeq, void, 3, 3,
"(int index)\n"
"Sets the animation to play for the viewed object.\n\n"
"\\param index The index of the animation to play.")
02/08/2009 (8:05 am)
its setSeq:ConsoleMethod(GuiObjectView, setSeq, void, 3, 3,
"(int index)\n"
"Sets the animation to play for the viewed object.\n\n"
"\\param index The index of the animation to play.")
#7
02/12/2009 (6:03 am)
Great work Jaimi
#8
I have tried setSeq(0); and setSeq("root"); and unfortunately the model displays correctly but the animation is never run. The animations are seperate DSQ files. Any suggesstions?
EDIT: Never mind ... it was a timing issue ... maybe I shouldn't work on my game when I haven't slept for like 2 days. :)
03/19/2009 (1:18 pm)
Excellent resource ... unfortunately as usual it is me and the dreaded SetSequence.I have tried setSeq(0); and setSeq("root"); and unfortunately the model displays correctly but the animation is never run. The animations are seperate DSQ files. Any suggesstions?
EDIT: Never mind ... it was a timing issue ... maybe I shouldn't work on my game when I haven't slept for like 2 days. :)
#10
Is ObjectView support that?
04/02/2009 (10:40 pm)
Sorry! I found something bugs when mount more than 2 times.objview.setMount("DTSfile",0);see the mount0objview.setMount("DTSfile",0);
objview.setMount("DTSfile",1);only see the mount1Is ObjectView support that?
#11
actually ObjectView can mount an object only to mount0 node.
I've modified the code to handle more than one object, it's not difficult, just an extension to the actual code.
Don't know if I find the time today to post here my code, anyways I'll do it as soon as possible.
04/10/2009 (1:51 am)
@ccljycactually ObjectView can mount an object only to mount0 node.
I've modified the code to handle more than one object, it's not difficult, just an extension to the actual code.
Don't know if I find the time today to post here my code, anyways I'll do it as soon as possible.
#12
First we need to store the objects models and their nodes so:
Now in the constructor, remove the
In the destructor replace the
Now the setMountedObject function
The renderWorld function
now we need only the script for the unMount function
Ok, that's all.
04/14/2009 (5:06 am)
Ok, here's the codeFirst we need to store the objects models and their nodes so:
enum Nodes { MAX_NODES = 6}; //Add this line
MouseState mMouseState;
TSShapeInstance* mModel;
TSShapeInstance* mMountedModel[MAX_NODES]; //we need a vector
U32 mSkinTag;
...
S32 mMountNode[MAX_NODES]; //
...
void unMount(S32 mountPoint); //the unmount function
void getMountedObjTransform(MatrixF* mat, S32 mPoint); //Changed this function to return the transform of the node mPoint
...Now in the constructor, remove the
... mMountModel(NULL), ... mMountNode(NO_NODE), ...and add in the constructor body this
for (int n=0; n<MAX_NODES; n++)
{
mMountedModel[n] = NULL;
mMountNode[n] = NO_NODE;
}In the destructor replace the
SAFE_DELETE(mMountedModel);with
for (int n=0; n<MAX_NODES; n++)
{
SAFE_DELETE(mMountedModel[n]);
}Now in the setObjectModel function change the code to this one...
// the first time recording
lastRenderTime = Platform::getVirtualMilliseconds();
char * mountName = new char[16];
for (int n=0; n<MAX_NODES; n++) //Loop to find all the mount nodes
{
dStrncpy(mountName, avar("mount%d", n), 15); //here we have n not 0
mMountNode[n] = mModel->getShape()->findNode(mountName);
}
delete [] mountName;
...Now the setMountedObject function
void GuiObjectView::setMountedObject(const char * modelName, S32 mountPoint)
{
SAFE_DELETE(mMountedModel[mountPoint]); //*****
// create a weapon for this dude
Resource<TSShape> model = ResourceManager::get().load(modelName);
if (! bool(model))
{
Con::warnf(avar("GuiObjectView: Failed to load mounted object model %s. Please check your model name and load a valid model.", modelName));
return;
}
/*
char * mountName = new char[16];
dStrncpy(mountName, avar("mount%d", 0), 15);
mMountNode = mModel->getShape()->findNode(mountName);
delete [] mountName;
*/ // code commented out because the mMountNode has been already initialized in the SetObjectModel function, if we haven't a model we shouldn't mount an object to it!
mMountedModel[mountPoint] = new TSShapeInstance(model, true);
AssertFatal(mMountedModel[mountPoint], avar("GuiObjectView: Failed to load mounted object model %s. Please check your model name and load a valid model.", modelName));
}The new unMount functionvoid GuiObjectView::unMount(S32 mountPoint)
{
SAFE_DELETE(mMountedModel[mountPoint]);
}and now the modified getMountedObjTransformvoid GuiObjectView::getMountedObjTransform(MatrixF * mat, S32 mPoint)
{
if ((! mMountedModel[mPoint]) || (mMountNode[mPoint] == NO_NODE))
{
// there is no mounted model or node to mount to
return;
}
MatrixF mountedTrans;
mountedTrans.identity();
S32 mountPoint = mMountedModel[mPoint]->getShape()->findNode("mountPoint");
if (mountPoint != -1)
mountedTrans = mMountedModel[mPoint]->mNodeTransforms[mountPoint];
Point3F mountedOffset = -mountedTrans.getPosition();
MatrixF modelTrans = mModel->mNodeTransforms[mMountNode[mPoint]];
modelTrans.mulP(mountedOffset);
modelTrans.setPosition(mountedOffset);
*mat = modelTrans;
}The renderWorld function
void GuiObjectView::renderWorld(const RectI &updateRect)
{
if ((! mModel) )//&& (! mMountedModel)) //remove the mMountedModel check
{
// nothing to render, punt
return;
}
...
if (mModel)
{
// MIKE J.
mModel->animate();
// MIKE J.
mModel->render();
}
for (int n=0; n<MAX_NODES; n++) //loop for each mounted object
{
if (mMountedModel[n])
{
// render a weapon
MatrixF mat;
getMountedObjTransform(&mat,n);
GFX->pushWorldMatrix();
GFX->multWorld( mat );
mMountedModel[n]->render();
GFX->popWorldMatrix();
}
}
F32 left, right, top, bottom, nearPlane, farPlane;
bool isOrtho;
...now we need only the script for the unMount function
ConsoleMethod(GuiObjectView, unMount, void, 3, 3, "(mountpoint)")
{
argc;
object->unMount(dAtoi(argv[2]));
}Ok, that's all.
#13
I can support mount objects ("mount0"~"mount31") now!
My changes are...
1.
2.void GuiObjectView::getMountedObjTransformByIndex(MatrixF * mat, S32 index) //new getMountedObjTransform
04/14/2009 (8:58 pm)
Thank You!I can support mount objects ("mount0"~"mount31") now!
My changes are...
1.
enum Nodes { MAX_MOUNT_NODE = 32}; //MAX_NODES2.void GuiObjectView::getMountedObjTransformByIndex(MatrixF * mat, S32 index) //new getMountedObjTransform
S32 mountPoint = mMountedModel->getShape()->findNode("mountPoint");ToS32 mountPoint = mMountedModel[index]->getShape()->findNode( avar("mount%d",index) ); //CCL add3.void GuiObjectView::renderWorld(const RectI &updateRect)for(int i=0;i<MAX_MOUNT_NODE;i++)
{
if (mMountedModel[i])
{...}
}Tofor(int i=0;i<MAX_MOUNT_NODE;i++)
{
if (mMountedModel[i] && (mMountNode[i]!=NO_NODE)) //CCL add
{...}It's working for me in TGEA 1.7.1
#14
05/26/2009 (9:51 pm)
Good!! Thanks Jaimi :D
#15
06/06/2009 (6:22 pm)
I added the code posted above from Davide Archetti, got a successful rebuild but I have a question about how to work it. I can still only get one object to mount at a time. Also the unmount function isn't being recognized, is the problem probably with my rebuild then?
#16
perhaps you should post the script you use, and check if there are some console errors.
06/06/2009 (11:09 pm)
@Jeffperhaps you should post the script you use, and check if there are some console errors.
#17
06/07/2009 (2:23 pm)
I hit 'rebuild solution' instead of 'rebuild "projectName"'. The unMount works just fine now, so I'm assuming so will mounting multiple objects.
#18
06/10/2009 (11:01 pm)
I tried changing the maxOrbitDist to 10 since my models are quite a bit larger then the player models. I get a successful rebuild, but the max is still 5, should I be changing something somewhere besides these values?GuiObjectView::GuiObjectView() : mMaxOrbitDist(10.0f), mMinOrbitDist(0.0f), mOrbitDist(10.0f),
#19
06/11/2009 (2:56 pm)
Broken link for file download (expired domain)?
#20
-> TSThread::setSequence: invalid shape handle, sequence number, or position.
setSeq not working. bug?
06/11/2009 (7:22 pm)
ObjectView.setSeq(1);-> TSThread::setSequence: invalid shape handle, sequence number, or position.
setSeq not working. bug?

Torque Owner Michael Branin
Default Studio Name