Game Development Community

mirrorSubobjects

by Desmond Fletcher · in Torque Game Engine · 11/24/2001 (6:15 pm) · 88 replies

I have not been able to get the mirrorSurface entity to work properly: when I place the mirrorSurface entity exactly on the surface to be a mirror, it always is the NULL texture (pink) when fully mirrored. If the surface texture has an alpha channel, the pink shows through that texture. So, looking at the mirrorSubobject code, I found this segment where it appears that the texture has been assigned NULL then is reassigned special/whiteAlpha0 (which is not in the common folder.

if (getInstance()->isClientObject() && mWhite == NULL)
mWhite = new TextureHandle "special/whiteAlpha0", MeshTexture);

So, I created my own alpha0 texture, created the common/special folder and replaced the above with:

mWhite = new TextureHandle("special/mirrorAlpha0", MeshTexture);

Still no change; then, while looking into the TextureHandle code saw that there is an InteriorTexture also. Well, I'm not trying to reflect the environmental image off a model so I replaced MeshTexture with InteriorTexture (why is MeshTexture there to begin with?):

mWhite = new TextureHandle("special/mirrorAlpha0", InteriorTexture);

Still no luck and no difference. Maybe I'm not looking in quite the right place; maybe the placement of the mirrorSurface entity is wrong; maybe, maybe, maybe--can anyone suggest a new direction to look?
#41
03/07/2003 (1:40 pm)
I agree but it's getting late here so I'll take up the search for the code on Saturday afternoon and hopefully get a look at it on Sunday.

In the meantime, a mirrored interior (cube?) would be most helpful.

- Melv.
#42
03/07/2003 (2:05 pm)
Here is some fixes for the objects/interiors not rendering through mirrored surfaces. Basically, the clip planes do not get oriented properly. I changed the mirrorSubObject to be a stencil mirror instead of a depth hack (never got it working properly...). Perhaps should be checked into the build, but here ya go (no idea how this will format...):

File: sceneGraph/sgUtil.h

Add:
void sgOrientClipPlanes(PlaneF * planes, const Point3F & camPos, const Point3F & leftUp, const Point3F & leftDown, const Point3F & rightUp, const Point3F & rightDown);

File: sceneGraph/sgUtil.cc

Add:
void sgOrientClipPlanes(PlaneF * planes, const Point3F & camPos, const Point3F & leftUp, const Point3F & leftDown, const Point3F & rightUp, const Point3F & rightDown)
{
   AssertFatal(planes, "orientClipPlanes: NULL planes ptr");

   planes[0].set(camPos,      leftUp,     leftDown);
   planes[1].set(camPos,      rightUp,    leftUp);
   planes[2].set(camPos,      rightDown,  rightUp);
   planes[3].set(camPos,      leftDown,   rightDown);
   planes[4].set(leftUp,      rightUp,    rightDown);

   // clip-planes through mirror portal are inverted
   PlaneF plane(leftUp, rightUp, rightDown);
   if(plane.whichSide(camPos) == PlaneF::Back)
      for(U32 i = 0; i < 5; i++)
         planes[i].invert();
}

File: sceneGraph/sceneTraversal.cc

Change:

void PotentialRenderList::setupClipPlanes(SceneState* state)
{
   mState = state;
   
   camPos = state->getCameraPosition();
   F32 farOverNear = state->getFarPlane() / state->getNearPlane();

   farPosLeftUp = Point3F(state->getBaseZoneState().frustum[0] * farOverNear, state->getFarPlane(), state->getBaseZoneState().frustum[3] * farOverNear);
   farPosLeftDown = Point3F(state->getBaseZoneState().frustum[0] * farOverNear, state->getFarPlane(), state->getBaseZoneState().frustum[2] * farOverNear);
   farPosRightUp = Point3F(state->getBaseZoneState().frustum[1] * farOverNear, state->getFarPlane(), state->getBaseZoneState().frustum[3] * farOverNear);
   farPosRightDown = Point3F(state->getBaseZoneState().frustum[1] * farOverNear, state->getFarPlane(), state->getBaseZoneState().frustum[2] * farOverNear);

   MatrixF temp = state->mModelview;
   temp.inverse();

   temp.mulP(farPosLeftUp);
   temp.mulP(farPosLeftDown);
   temp.mulP(farPosRightUp);
   temp.mulP(farPosRightDown);

   mBox.min = camPos;
   mBox.min.setMin(farPosLeftUp);
   mBox.min.setMin(farPosLeftDown);
   mBox.min.setMin(farPosRightUp);
   mBox.min.setMin(farPosRightDown);
   mBox.max = camPos;
   mBox.max.setMax(farPosLeftUp);
   mBox.max.setMax(farPosLeftDown);
   mBox.max.setMax(farPosRightUp);
   mBox.max.setMax(farPosRightDown);

   sgOrientClipPlanes(&viewPlanes[0], camPos, farPosLeftUp, farPosLeftDown, farPosRightUp, farPosRightDown);
}

File: sceneGraph/sceneState.cc

Change:
void SceneState::setupClipPlanes(ZoneState& rState)
{
   F32 farOverNear = getFarPlane() / getNearPlane();

   Point3F farPosLeftUp = Point3F(rState.frustum[0] * farOverNear, getFarPlane(), rState.frustum[3] * farOverNear);
   Point3F farPosLeftDown = Point3F(rState.frustum[0] * farOverNear, getFarPlane(), rState.frustum[2] * farOverNear);
   Point3F farPosRightUp = Point3F(rState.frustum[1] * farOverNear, getFarPlane(), rState.frustum[3] * farOverNear);
   Point3F farPosRightDown = Point3F(rState.frustum[1] * farOverNear, getFarPlane(), rState.frustum[2] * farOverNear);

   MatrixF temp = mModelview;
   temp.inverse();

   temp.mulP(farPosLeftUp);
   temp.mulP(farPosLeftDown);
   temp.mulP(farPosRightUp);
   temp.mulP(farPosRightDown);

   sgOrientClipPlanes(&rState.clipPlanes[0], getCameraPosition(), farPosLeftUp, farPosLeftDown, farPosRightUp, farPosRightDown);
   rState.clipPlanesValid = true;
}



Hopefully I didn't forget anything here...

--- john
#43
03/07/2003 (2:14 pm)
this is very cool I should go try it!

tx John.
#44
03/07/2003 (2:17 pm)
Melv:

Your right, we never got the depth mirrors to work properly (fixing one thing always lead to 2 others...), and decided to do stencil mirrors instead.

While were on the topic, suppose I should just post the mirror changes. The following is the mirrorSubObject code using stencil mirrors. There are a few issues with multiple mirrors overlapping and when camera is close to mirror surface (near plane colliding with mirrored surface I believe). This is a rather basic implementation, fixes and additions can be left up to the reader ;)

File: interior/mirrorSubObject.cc (header is pretty much unchanged I believe...)

//-----------------------------------------------------------------------------
// Torque Game Engine
// 
// Copyright (c) 2001 GarageGames.Com
// Portions Copyright (c) 2001 by Sierra Online, Inc.
//-----------------------------------------------------------------------------

#include "interior/mirrorSubObject.h"
#include "interior/interiorInstance.h"
#include "interior/interior.h"
#include "interior/interiorMaterials.h"
#include "core/stream.h"
#include "dgl/dgl.h"
#include "sceneGraph/sgUtil.h"


IMPLEMENT_CONOBJECT(MirrorSubObject);

#include "platform/platformVideo.h"
#include "sceneGraph/sceneGraph.h"

//--------------------------------------------------------------------------
MirrorSubObject::MirrorSubObject()
{
   mTypeMask = StaticObjectType;

   mInitialized = false;
}

MirrorSubObject::~MirrorSubObject()
{
}

//--------------------------------------------------------------------------
void MirrorSubObject::initPersistFields()
{
   Parent::initPersistFields();

   //
}

//--------------------------------------------------------------------------
void MirrorSubObject::renderObject(SceneState* state, SceneRenderImage* image)
{
   // the surface is rendered when the portal is closed
   return;
}

//--------------------------------------------------------------------------
void MirrorSubObject::transformModelview(const U32 portalIndex, const MatrixF& oldMV, MatrixF* pNewMV)
{
   AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!");
   AssertFatal(portalIndex == 0, "Error, we only have one portal!");

   *pNewMV = oldMV;
   pNewMV->mul(mReflectionMatrix);
}

//--------------------------------------------------------------------------
void MirrorSubObject::transformPosition(const U32 portalIndex, Point3F& ioPosition)
{
   AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!");
   AssertFatal(portalIndex == 0, "Error, we only have one portal!");

   mReflectionMatrix.mulP(ioPosition);
}

//--------------------------------------------------------------------------
bool MirrorSubObject::computeNewFrustum(const U32      portalIndex,
                                        const F64*     oldFrustum,
                                        const F64      nearPlane,
                                        const F64      farPlane,
                                        const RectI&   oldViewport,
                                        F64*           newFrustum,
                                        RectI&         newViewport,
                                        const bool     flippedMatrix)
{
   AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!");
   AssertFatal(portalIndex == 0, "Error, mirrortests only have one portal!");

   Interior* interior = getInstance()->getDetailLevel(mDetailLevel);
   
   static Vector<SGWinding> mirrorWindings;
   mirrorWindings.setSize(surfaceCount);

   for (U32 i = 0; i < surfaceCount; i++) {
      SGWinding& rSGWinding             = mirrorWindings[i];
      const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart + i];

      U32 fanIndices[32];
      U32 numFanIndices = 0;
      interior->collisionFanFromSurface(rSurface, fanIndices, &numFanIndices);

      for (U32 j = 0; j < numFanIndices; j++)
         rSGWinding.points[j] = interior->mPoints[fanIndices[j]].point;
      rSGWinding.numPoints = numFanIndices;
   }

   MatrixF finalModelView;
   dglGetModelview(&finalModelView);
   finalModelView.mul(getSOTransform());
   finalModelView.scale(getSOScale());

   return sgComputeNewFrustum(oldFrustum, nearPlane, farPlane,
                              oldViewport,
                              mirrorWindings.address(), mirrorWindings.size(),
                              finalModelView,
                              newFrustum, newViewport,
                              flippedMatrix);
}


//--------------------------------------------------------------------------
void MirrorSubObject::openPortal(const U32   portalIndex,
                                 SceneState* pCurrState,
                                 SceneState* pParentState)
{
   AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!");
   AssertFatal(portalIndex == 0, "Error, mirrortests only have one portal!");

   if (mZone == 0)
      pParentState->setupZoneProjection(getInstance()->getCurrZone(0));
   else
      pParentState->setupZoneProjection(mZone + getInstance()->getZoneRangeStart() - 1);

   // setup transformation
   glPushMatrix();
   dglMultMatrix(&getSOTransform());
   glScalef(getSOScale().x, getSOScale().y, getSOScale().z);

   // setup stencil buffer:
   glClearStencil(0x0);
   glStencilMask(~0u);
   glEnable(GL_STENCIL_TEST);

   static U32 lastStateKey = 0;
   U32 stateKey = gClientSceneGraph->getStateKey();

   // dont clear the stencil for every portal   
   if(lastStateKey != stateKey)
   {
      lastStateKey = stateKey;
      glClear(GL_STENCIL_BUFFER_BIT);
   }

   // clear with the fog color
   ColorF fogColor = gClientSceneGraph->getFogColor();
   glColor3f(fogColor.red, fogColor.green, fogColor.blue);

   Interior * interior = getInstance()->getDetailLevel(mDetailLevel);
   glEnableClientState(GL_VERTEX_ARRAY);
   glVertexPointer(3, GL_FLOAT, sizeof(ItrPaddedPoint), interior->mPoints.address());

   // render the visible surface into the stencil buffer (also render the fog color
   // since terrain may not be rendered and it assumes a fog clear)
   glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
   glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

   for (U32 i = 0; i < surfaceCount; i++) 
   {
      glDrawElements(GL_TRIANGLE_STRIP,
                     interior->mSurfaces[surfaceStart+i].windingCount,
                     GL_UNSIGNED_INT,
                     &interior->mWindings[interior->mSurfaces[surfaceStart+i].windingStart]);
   }

   // now clear the visible surface depth (use stencil). disable color buffers (already
   // rendered fog in previous step).
   glDepthRange(1, 1);
   glDepthFunc(GL_ALWAYS);
   glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

   glStencilFunc(GL_EQUAL, 1, 0xffffffff);
   glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

   for (U32 i = 0; i < surfaceCount; i++) 
   {
      glDrawElements(GL_TRIANGLE_STRIP,
                     interior->mSurfaces[surfaceStart+i].windingCount,
                     GL_UNSIGNED_INT,
                     &interior->mWindings[interior->mSurfaces[surfaceStart+i].windingStart]);
   }

   // reset states (stencil is setup correctly)
   glDepthFunc(GL_LEQUAL);
   glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
   glDepthRange(0, 1);

   glDisableClientState(GL_VERTEX_ARRAY);

   // reset transform
   glPopMatrix();
   dglSetCanonicalState();
}

void MirrorSubObject::closePortal(const U32   portalIndex,
                                  SceneState* pCurrState,
                                  SceneState* pParentState)
{
   AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!");
   AssertFatal(portalIndex == 0, "Error, mirrortests only have one portal!");

   // setup transformation
   glPushMatrix();
   dglMultMatrix(&getSOTransform());
   glScalef(getSOScale().x, getSOScale().y, getSOScale().z);

   // update depth over portal
   Interior * interior = getInstance()->getDetailLevel(mDetailLevel);
   glEnableClientState(GL_VERTEX_ARRAY);
   glVertexPointer(3, GL_FLOAT, sizeof(ItrPaddedPoint), interior->mPoints.address());

   // want to clear stencil value
   glStencilFunc(GL_EQUAL, 1, 0xffffffff);
   glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);

   // render the alpha surface
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


   glActiveTextureARB(GL_TEXTURE0_ARB);
   glEnable(GL_TEXTURE_2D);

   glEnable(GL_TEXTURE_GEN_S);
   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
   glEnable(GL_TEXTURE_GEN_T);
   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

   glActiveTextureARB(GL_TEXTURE1_ARB);
   glEnable(GL_TEXTURE_2D);

   glEnable(GL_TEXTURE_GEN_S);
   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
   glEnable(GL_TEXTURE_GEN_T);
   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);


   glActiveTextureARB(GL_TEXTURE0_ARB);

   glEnableClientState(GL_VERTEX_ARRAY);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);


   glBindTexture(GL_TEXTURE_2D, interior->mMaterialList->getMaterial(interior->mSurfaces[surfaceStart].textureIndex).getGLName());


   glActiveTextureARB(GL_TEXTURE1_ARB);
   Vector<U8>* pLMapIndices = &interior->mNormalLMapIndices;
   U8 baseIndex = (*pLMapIndices)[surfaceStart];
   TextureHandle *tex = gInteriorLMManager.getHandle( interior->mLMHandle, getInstance()->getLMHandle(), baseIndex); 
   glBindTexture(GL_TEXTURE_2D, tex->getGLName() );



   glActiveTextureARB(GL_TEXTURE0_ARB);
   glTexGenfv(GL_S, GL_OBJECT_PLANE, (GLfloat*)interior->mTexGenEQs[interior->mSurfaces[surfaceStart].texGenIndex].planeX);
   glTexGenfv(GL_T, GL_OBJECT_PLANE, (GLfloat*)interior->mTexGenEQs[interior->mSurfaces[surfaceStart].texGenIndex].planeY);

   glActiveTextureARB(GL_TEXTURE1_ARB);


   glColor4f(1, 1, 1, mAlphaLevel);

   for (U32 i = 0; i < surfaceCount; i++) {

      glTexGenfv(GL_S, GL_OBJECT_PLANE, (GLfloat*)interior->mLMTexGenEQs[surfaceStart+i].planeX);
      glTexGenfv(GL_T, GL_OBJECT_PLANE, (GLfloat*)interior->mLMTexGenEQs[surfaceStart+i].planeY);


      glDrawElements(GL_TRIANGLE_STRIP,
                     interior->mSurfaces[surfaceStart+i].windingCount,
                     GL_UNSIGNED_INT,
                     &interior->mWindings[interior->mSurfaces[surfaceStart+i].windingStart]);
   }

   glDisableClientState(GL_VERTEX_ARRAY);

   glActiveTextureARB(GL_TEXTURE0_ARB);
   glDisable(GL_TEXTURE_GEN_S);
   glDisable(GL_TEXTURE_GEN_T);

   glActiveTextureARB(GL_TEXTURE1_ARB);
   glDisable(GL_TEXTURE_GEN_S);
   glDisable(GL_TEXTURE_GEN_T);
   glDisable(GL_TEXTURE_2D);

   glActiveTextureARB(GL_TEXTURE0_ARB);

   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);

   glDepthFunc(GL_LEQUAL);

   // reset transform
   glPopMatrix();

   // disable stencil test
   glDisable(GL_STENCIL_TEST);
   
   dglSetCanonicalState();
}

//--------------------------------------------------------------------------
bool MirrorSubObject::needPortalClipPlane()
{
   return(true);
}

void MirrorSubObject::getWSPortalPlane(const U32 portalIndex, PlaneF* pPlane)
{
   AssertFatal(portalIndex == 0, "Error, mirrortests only have one portal!");

   Interior* interior = getInstance()->getDetailLevel(mDetailLevel);
   const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart];

   PlaneF temp = interior->getPlane(rSurface.planeIndex);
   if (Interior::planeIsFlipped(rSurface.planeIndex))
      temp.neg();

   mTransformPlane(getSOTransform(), getSOScale(), temp, pPlane);
}


//--------------------------------------------------------------------------
U32 MirrorSubObject::getSubObjectKey() const
{
   return InteriorSubObject::MirrorSubObjectKey;
}


bool MirrorSubObject::_readISO(Stream& stream)
{
   AssertFatal(isInitialized() == false, "Error, should not be initialized here!");

   if (Parent::_readISO(stream) == false)
      return false;

   stream.read(&mDetailLevel);
   stream.read(&mZone);
   stream.read(&mAlphaLevel);
   stream.read(&surfaceCount);
   stream.read(&surfaceStart);

   stream.read(&mCentroid.x);
   stream.read(&mCentroid.y);
   stream.read(&mCentroid.z);

   return true;
}


bool MirrorSubObject::_writeISO(Stream& stream) const
{
   if (Parent::_writeISO(stream) == false)
      return false;

   stream.write(mDetailLevel);
   stream.write(mZone);
   stream.write(mAlphaLevel);
   stream.write(surfaceCount);
   stream.write(surfaceStart);

   stream.write(mCentroid.x);
   stream.write(mCentroid.y);
   stream.write(mCentroid.z);

   return true;
}


SubObjectRenderImage* MirrorSubObject::getRenderImage(SceneState*    state,
                                                      const Point3F& osPoint)
{
   if (isInitialized() == false)
      setupTransforms();

   // Check to make sure that we're on the right side of the plane...
   Interior* interior = getInstance()->getDetailLevel(mDetailLevel);
   const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart];

   PlaneF plane = interior->getPlane(rSurface.planeIndex);
   if (Interior::planeIsFlipped(rSurface.planeIndex))
      plane.neg();

   if (plane.whichSide(osPoint) != PlaneF::Front)
      return NULL;

   // On the right side, guess we have to return an image and a portal...
   //
   SubObjectRenderImage* ri = new SubObjectRenderImage;

   ri->obj           = this;
   ri->isTranslucent = false;

   U32 realZone;
   if (getInstance()->getZoneRangeStart() == 0xFFFFFFFF || mZone == 0) {
      realZone = getInstance()->getCurrZone(0);
   } else {
      realZone = getInstance()->getZoneRangeStart() + mZone - 1;
   }

   // Create the WS start point.  this will be the centroid of the first poly in os space,
   //  transformed out for the sceneGraph, with a smidge of our normal added in to pull
   //  it off the surface plane...

   Point3F startPoint = mCentroid;
   PlaneF temp = interior->getPlane(rSurface.planeIndex);
   if (Interior::planeIsFlipped(rSurface.planeIndex))
      temp.neg();
   startPoint += Point3F(temp.x, temp.y, temp.z) * 0.01f;
   getSOTransform().mulP(startPoint);
   startPoint.convolve(getSOScale());

   state->insertTransformPortal(this, 0, realZone, startPoint, true);

   return ri;
}


bool MirrorSubObject::renderDetailDependant() const
{
   return true;
}


U32 MirrorSubObject::getZone() const
{
   return mZone;
}


void MirrorSubObject::setupTransforms()
{
   mInitialized = true;

   Interior* interior = getInstance()->getDetailLevel(mDetailLevel);
   const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart];

   for( U32 i=0; i<surfaceCount; i++ )
   {
      Interior::Surface& surface = interior->mSurfaces[surfaceStart + i];
      surface.mirrored = true;
   }



   PlaneF plane = interior->getPlane(rSurface.planeIndex);
   if (Interior::planeIsFlipped(rSurface.planeIndex))
      plane.neg();

   Point3F n(plane.x, plane.y, plane.z);
   Point3F q = n;
   q *= -plane.d;

   MatrixF t(true);
   t.scale(getSOScale());
   t.mul(getSOTransform());

   t.mulV(n);
   t.mulP(q);

   F32* ra = mReflectionMatrix;

   ra[0]  = 1.0f - 2.0f*(n.x*n.x); ra[1]  = 0.0f - 2.0f*(n.x*n.y); ra[2]  = 0.0f - 2.0f*(n.x*n.z); ra[3]  = 0.0f;
   ra[4]  = 0.0f - 2.0f*(n.y*n.x); ra[5]  = 1.0f - 2.0f*(n.y*n.y); ra[6]  = 0.0f - 2.0f*(n.y*n.z); ra[7]  = 0.0f;
   ra[8]  = 0.0f - 2.0f*(n.z*n.x); ra[9]  = 0.0f - 2.0f*(n.z*n.y); ra[10] = 1.0f - 2.0f*(n.z*n.z); ra[11] = 0.0f;

   Point3F qnn = n * mDot(n, q);

   ra[12] = qnn.x * 2.0f;
   ra[13] = qnn.y * 2.0f;
   ra[14] = qnn.z * 2.0f;
   ra[15] = 1.0f;

   // Now, the GGems series (as of v1) uses row vectors (arg)
   mReflectionMatrix.transpose();
}

void MirrorSubObject::noteTransformChange()
{
   setupTransforms();
   Parent::noteTransformChange();
}

InteriorSubObject* MirrorSubObject::clone(InteriorInstance* instance) const
{
   MirrorSubObject* pClone = new MirrorSubObject;

   pClone->mDetailLevel = mDetailLevel;
   pClone->mZone        = mZone;
   pClone->mAlphaLevel  = mAlphaLevel;
   pClone->mCentroid    = mCentroid;
   pClone->surfaceCount = surfaceCount;
   pClone->surfaceStart = surfaceStart;

   pClone->mInteriorInstance = instance;

   return pClone;
}
#45
03/07/2003 (2:19 pm)
Nice one John.

I was bored of looking through my zip disks anyway!

I guess I'm going to need another distraction now ... Hmmmm. ;)

- Melv.
#46
03/07/2003 (2:47 pm)
Thx for the code, John... unfortunately, I couldn't get it to compile ...
mirrorSubObject.cc
D:\checkouts\ToRK3\ToRK2\engine\interior\mirrorSubObject.cc(11) : fatal error C1083: Cannot open include file: 'interior/interiorMaterials.h': No such file or directory
Error executing cl.exe.
and after commenting that out:
D:\checkouts\ToRK3\ToRK2\engine\interior\mirrorSubObject.cc(138) : error C2039: 'getStateKey' : is not a member of 'SceneGraph'
        ../engine\sceneGraph/sceneGraph.h(64) : see declaration of 'SceneGraph'
D:\checkouts\ToRK3\ToRK2\engine\interior\mirrorSubObject.cc(309) : error C2039: 'needPortalClipPlane' : is not a member of 'MirrorSubObject'
        ../engine\interior/mirrorSubObject.h(17) : see declaration of 'MirrorSubObject'
D:\checkouts\ToRK3\ToRK2\engine\interior\mirrorSubObject.cc(447) : error C2039: 'mirrored' : is not a member of 'Surface'
        ../engine\interior/interior.h(416) : see declaration of 'Surface'
Especially the "getStateKey" concerns me, the others seem pretty easy to add/fix... any idea what is different in your code base?
Thanks a lot! :)
#47
03/07/2003 (2:57 pm)
Um.. your problems are all with code that is generally not needed in the base Torque. Hopefully this will help:

1: interior/interiorMaterisl.h: just remove this.. you wont need it

2: getKeyState(): Add this to the public interface of sceneGraph.h:

U32 getStateKey()       { return(smStateKey); }

3: needPortalClipPlane(): just remove, you shouldn't need this

4: surface flag 'mirrored': remove this as well.. you shouldn't need this (as long as your getting the surface into the mirrorSubObject it should work).

--- john
#48
03/08/2003 (1:53 am)
John!
Thx a million, that did the trick and now the mirrors work! :D
Interiors, statics, players, everything gets rendered! :)
Check it out here: tork.zenkel.com/uploads/pics/mirrors_working.jpg
#49
03/08/2003 (2:21 am)
that is sweet work man
now make a patch for the head and post it!!!!
#50
03/08/2003 (2:37 am)
Hmm, Melv, shouldnt you distract yourself by FINISHING YOUR BLOODY GAME!!! :))

Badguy.. I always miss the cool threads, where's the AI thingy you posted?

Phil.
#52
03/08/2003 (5:08 am)
Phil,

Naw, if you look at the same bits of code too long your head fills up with mud and shuts down. A little distraction now and again is good for business. :)

- Melv.
#53
03/08/2003 (8:44 am)
Just a note to John's excellent work above:
both sceneState.cc and sceneTraversal.cc need the following include added:

#include "sceneGraph/sgUtil.h"

Also, only one mirror can be in an interior zone at this time. Multiple mirrors in zone 0 works fine.
#54
03/08/2003 (11:39 am)
If one of you guys wants to send me a patch (probably with a simple mirror so that I can test it's working) then I'll get this into the [HEAD] for you.

- Melv.
#55
03/08/2003 (12:42 pm)
You ALL rock. :)
#56
03/08/2003 (1:59 pm)
is anyone gonna make the head patch?
someone who has already installed this maybe?
I will do it if there are no takers .. but I would have to know asap im leaving town for a week in a couple days.
#57
03/08/2003 (2:51 pm)
Thats wierd... Nobody seems to want the rest of us to use this feature... SERVE THE GREATER GOOD AND PATCH HEAD!
#58
03/08/2003 (6:28 pm)
Chill, guys... Melv already said he was going to try and get this into HEAD.

Give the man a few days to get it done. :)
#59
03/09/2003 (1:45 am)
Looks great! just one thing I was thinking as I haven't been to help with the emapping.

So, is there away to say replace the emapping with this? as then would be alot more realistic :-).

Or would it prove very hard?
#60
03/09/2003 (1:49 am)
Very Cool!

-J