Constructing t2d shapes on the fly..
by Jason Booth · in Torque Game Builder · 01/28/2006 (8:32 am) · 9 replies
So, I'm interested in generating t2d shape geometry on the fly. Basically, I need to make a 2d side view procedural terrain which can be destroyed, deformed and animated. So it would make sense to me to construct this out of verticies and perform some kind of physics simulation on the whole mass for animation and collapsing. Eventually, I'll also want some method to generate the texture for it, but for now anything should be fine.
Obviously this is outside the realm of script; but are thier any good docs available to a t2d owner on constructing dts shapes from c++ code? Are thier even calls for doing this kind of stuff right now, or will I have to add my own system to generate the data? Are thier max or maya exporters for this type of data? It would probrably make sense for me to get it working first and worry about generation later.
Has anyone done anything like this in t2d?
Obviously this is outside the realm of script; but are thier any good docs available to a t2d owner on constructing dts shapes from c++ code? Are thier even calls for doing this kind of stuff right now, or will I have to add my own system to generate the data? Are thier max or maya exporters for this type of data? It would probrably make sense for me to get it working first and worry about generation later.
Has anyone done anything like this in t2d?
About the author
#2
02/14/2006 (12:43 pm)
Ah. This thread is a bit out of date now (I have the 2d shape version working) but still relivant. I would prefer to use a 3d object so I can apply a texture; which isn't possible with a 2dShape right now. But when I originally looked into this, I couldn't find any documentation on how to create 3d shapes from within script. Perhaps it's because I'm only a 2d licence holder? Is there something similiar to the customPoly attribute I can use, but with UVs?
#3
02/14/2006 (12:54 pm)
Jason search for 3d shapes in T2D .. there is an excellent TDn tutorial on it that will get you up and running in < 30 minutes.
#4
02/14/2006 (2:06 pm)
Yeah, I found that tutorial; but it doesn't really go into creating 3d shapes from code; only loading a dts which allready exists on disk somewhere and using it. Since I want to procedurally generate my shape, I want to create that shape in code with something similiar to the setCustomPoly function on t2dshapes. Basically constructing the verticies and UV coordinates on the fly. I haven't been able to find any information on doing that aspect of it though.
#5
Just give me a few minutes to find the build (I have like 10 prototypes on my system)
02/14/2006 (2:12 pm)
I will post the source for my custom planet object... It's from a build of TGE 1.4 ... but you can probably use it to create the same effect in T2D.Just give me a few minutes to find the build (I have like 10 prototypes on my system)
#6
02/14/2006 (2:16 pm)
Here we go. This simply draws a textured quad:#include "dgl/dgl.h"
#include "console/consoleTypes.h"
#include "core/bitStream.h"
#include "math/mathIO.h"
#include "game/gameConnection.h"
#include "console/simBase.h"
#include "sceneGraph/sceneGraph.h"
#include "sceneGraph/sgUtil.h"
#include "planet.h"
extern bool gEditingMission;
IMPLEMENT_CO_NETOBJECT_V1(planet);
//------------------------------------------------------------------------------
// Class: planet
//------------------------------------------------------------------------------
planet::planet()
{
// Setup NetObject.
mTypeMask |= StaticObjectType | StaticTSObjectType | StaticRenderedObjectType;
mNetFlags.set(Ghostable);
// Reset Last Render Time.
mLastRenderTime = 0;
// Texture Handle.
mTextureHandle = NULL;
// Flare Texture Name.
mTextureName = StringTable->insert("");
// Reset Quad Size.
mQuadSize = 5.0f;
// Reset Quad Rotate Speed.
mQuadRotateSpeed = 90.0f;
// Reset Current Angle.
mCurrentAngle = 0.0f;
}
//------------------------------------------------------------------------------
planet::~planet()
{
}
//------------------------------------------------------------------------------
void planet::initPersistFields()
{
// Initialise parents' persistent fields.
Parent::initPersistFields();
// Add out own persistent fields.
//addGroup( "MyFirstGroup1" );
addField( "QuadSize", TypeF32, Offset( mQuadSize, planet ) );
addField( "QuadRotateSpeed",TypeF32, Offset( mQuadRotateSpeed, planet ) );
addField( "Texture", TypeFilename, Offset( mTextureName, planet ) );
//enddGroup( "MyFirstGroup1" );
}
//------------------------------------------------------------------------------
bool planet::onAdd()
{
if(!Parent::onAdd()) return(false);
// Calculate Quad Radius.
F32 QuadHalfSize = mQuadSize / 2.0f;
// Set initial bounding box.
//
// NOTE:- Set this box to completely encapsulate your object.
// You must reset the world box and set the render transform
// after changing this.
mObjBox.min.set( -QuadHalfSize, -0.5f, -QuadHalfSize );
mObjBox.max.set( QuadHalfSize, +0.5f, QuadHalfSize );
// Reset the World Box.
resetWorldBox();
// Set the Render Transform.
setRenderTransform(mObjToWorld);
// Add to Scene.
addToScene();
// Return OK.
return(true);
}
//------------------------------------------------------------------------------
void planet::onRemove()
{
// Remove from Scene.
removeFromScene();
// Do Parent.
Parent::onRemove();
}
//------------------------------------------------------------------------------
void planet::inspectPostApply()
{
// Set Parent.
Parent::inspectPostApply();
// Set fxPortal Mask.
setMaskBits(planetMask);
}
//------------------------------------------------------------------------------
void planet::onEditorEnable()
{
}
//------------------------------------------------------------------------------
void planet::onEditorDisable()
{
}
//------------------------------------------------------------------------------
bool planet::prepRenderImage( SceneState* state, const U32 stateKey, const U32 startZone,
const bool modifyBaseZoneState)
{
// Return if last state.
if (isLastState(state, stateKey)) return false;
// Set Last State.
setLastState(state, stateKey);
// Is Object Rendered?
if (state->isObjectRendered(this))
{
// Yes, so get a SceneRenderImage.
SceneRenderImage* image = new SceneRenderImage;
// Populate it.
image->obj = this;
image->isTranslucent = false;
image->sortType = SceneRenderImage::Normal;
// Insert it into the scene images.
state->insertRenderImage(image);
}
return false;
}
//------------------------------------------------------------------------------
#7
02/14/2006 (2:16 pm)
void planet::renderObject(SceneState* state, SceneRenderImage*)
{
// Check we are in Canonical State.
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");
// Calculate Elapsed Time and take new Timestamp.
S32 Time = Platform::getVirtualMilliseconds();
F32 ElapsedTime = (Time - mLastRenderTime) * 0.001f;
mLastRenderTime = Time;
// Return if we don't have a texture.
if (!mTextureHandle) return;
// Save state.
RectI viewport;
// Save Projection Matrix so we can restore Canonical state at exit.
glMatrixMode(GL_PROJECTION);
glPushMatrix();
// Save Viewport so we can restore Canonical state at exit.
dglGetViewport(&viewport);
// Setup the projection to the current frustum.
//
// NOTE:- You should let the SceneGraph drive the frustum as it
// determines portal clipping etc.
// It also leaves us with the MODELVIEW current.
//
state->setupBaseProjection();
// Save ModelView Matrix so we can restore Canonical state at exit.
glPushMatrix();
// Transform by the objects' transform e.g move it.
dglMultMatrix(&getTransform());
// Rotate by Rotate Speed.
//
// NOTE:- We use the elapsed time as a coeficient,
// that way we get consistent rotational speed
// independant of frame-rate.
//
mCurrentAngle += mFmod(mQuadRotateSpeed * ElapsedTime, 360);
// Rotate Quad by current roation.
glRotatef(mCurrentAngle, 1,1,1);
// Setup our rendering state (alpha blending).
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Enable Texturing.
glEnable(GL_TEXTURE_2D);
// Select the objects' texture.
glBindTexture(GL_TEXTURE_2D, mTextureHandle.getGLName());
// Set Colour/Alpha.
glColor4f(1,1,1,1);
// Calculate Quad Radius.
F32 QuadHalfSize = mQuadSize / 2.0f;
// Draw a Quad.
//
// NOTE:- We draw in object space here and *not* world-space.
// Notice that Z is UP in this system and XY lie on the terrain plane.
//
glBegin(GL_QUADS);
glTexCoord2f(0,0);
glVertex3f(-QuadHalfSize,0,+QuadHalfSize);
glTexCoord2f(1,0);
glVertex3f(+QuadHalfSize,0,+QuadHalfSize);
glTexCoord2f(1,1);
glVertex3f(+QuadHalfSize,0,-QuadHalfSize);
glTexCoord2f(0,1);
glVertex3f(-QuadHalfSize,0,-QuadHalfSize);
glEnd();
// Restore our canonical rendering state.
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
// Restore our canonical matrix state.
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
// Restore our canonical viewport state.
dglSetViewport(viewport);
// Check we have restored Canonical State.
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
}
//------------------------------------------------------------------------------
U32 planet::packUpdate(NetConnection * con, U32 mask, BitStream * stream)
{
// Pack Parent.
U32 retMask = Parent::packUpdate(con, mask, stream);
// Write fxPortal Mask Flag.
if (stream->writeFlag(mask & planetMask))
{
// Write Object Transform.
stream->writeAffineTransform(mObjToWorld);
// Write Texture Name.
stream->writeString(mTextureName);
// Write Quad Size.
stream->write(mQuadSize);
// Write Quad Rotate Speed.
stream->write(mQuadRotateSpeed);
}
// Were done ...
return(retMask);
}
//------------------------------------------------------------------------------
void planet::unpackUpdate(NetConnection * con, BitStream * stream)
{
// Unpack Parent.
Parent::unpackUpdate(con, stream);
// Read fxPortal Mask Flag.
if(stream->readFlag())
{
MatrixF ObjectMatrix;
// Read Object Transform.
stream->readAffineTransform(&ObjectMatrix);
// Read Texture Name.
mTextureName = StringTable->insert(stream->readSTString());
// Read Quad Size.
stream->read(&mQuadSize);
// Read Quad Rotate Speed.
stream->read(&mQuadRotateSpeed);
// Set Transform.
setTransform(ObjectMatrix);
// Reset our previous texture handle.
mTextureHandle = NULL;
// Load the texture (if we've got one)
if (*mTextureName) mTextureHandle = TextureHandle(mTextureName, BitmapTexture, true);
// Calculate Quad Radius.
F32 QuadHalfSize = mQuadSize / 2.0f;
// Set bounding box.
//
// NOTE:- Set this box to completely encapsulate your object.
// You must reset the world box and set the render transform
// after changing this.
mObjBox.min.set( -QuadHalfSize, -0.5f, -QuadHalfSize );
mObjBox.max.set( QuadHalfSize, +0.5f, QuadHalfSize );
// Reset the World Box.
resetWorldBox();
// Set the Render Transform.
setRenderTransform(mObjToWorld);
}
}
#8
02/14/2006 (2:32 pm)
So the functions to create 3dshapes are only available via the c++ api? Ok; not a big deal, as I'm going to want to use something faster than script for deformation, destruction, and other effects I'm planning anyway. As always, thanks for the help Chris.
#9
02/14/2006 (2:35 pm)
No problem... and creating 3dshapes normally is through script... but this is custom. Should still work just as well though.
Torque Owner Chris Labombard
Premium Preferred