Jump to content

Steve_Yorkshire

Contributor
  • Posts

    353
  • Joined

  • Last visited

Posts posted by Steve_Yorkshire

  1. And what is it good for?

    Invoking satan and his many little wizards ... Chromotic Abberation is literally the devil ...

    I think it's from the big library of postFX shaders which is still available via the download in the resource on GG.


    EDIT: If you're gonna use any of those you might want to swap the renderBin = "glowBin" to "ObjTranslucentBin". Just sayin'.


    EDIT2: actually you probably want to swap renderTime= "PFXAfterBin" to renderTime = "PFXAfterDiffuse" or particles and transparent objects won't get affected by them. Anyhow, it's still a useful resource.

  2. 1: make a skybox which features mountains

    2: use a bigger terrain mesh and make mountains on the edges

    3: make a small model of mountains with a hole in the middle and no collisions then scale it really big in the editor so it surrounds your terrain and looks like mountains in the distance (how CoD did it).

  3. filename ExplosionData::explosionShape


    Optional DTS or DAE shape to place at the center of the explosion.

    The ambient animation of this model will be played automatically at the start of the explosion.


    bool ExplosionData::faceViewer


    Controls whether the visual effects of the explosion always face the camera.

     

    I've been using explosionShape for a while and have come up with an improvement. :idea:


    In stock T3D the model for an explosionShape spawns in game with the rotation of it's impact. This is fine for vertical collision but means that striking a horizontal contact flips the model 90 degrees. If you wanted to spawn an explosion by script - without an impact vector/rotation you would have to export the animated model facing the Y-axis for it's "up" - but then it would be bent 90 degrees if it was used for a standard collision impact.


    But wait! There's more!


    Using faceViewer=bool; was also funky as it would billboard it's rotation towards the camera, half the model would end up buried beneath the terrain and faceViewer had a random Y rotation in it's code.


    Non of this is helpful if you want your animated mesh explosion to align upwards (Z axis) - for instance a nuclear mushroom cloud or a shockwave along the ground.


    What would be useful is a faceZ(bool) variable which works like particleEmitter's alignDirection = "0 0 1"; and make the model always stand up along the z-axis. And here it is! :P


    source/T3D/fx/explosion.h

    class ExplosionData : public GameBaseData {
    //...
      public:
       StringTableEntry dtsFileName;
     
       bool faceViewer;
       bool faceZ;//yorks in ~line 62
     
       S32 particleDensity;
    //...

     

    source/T3D/fx/explosion.cpp

    ExplosionData::ExplosionData()
    {
    //...
     
       faceViewer   = false;
       faceZ		= false;//yorks in ~line 226
     
       soundProfile      = NULL;
    //...
     
    void ExplosionData::initPersistFields()
    {
    //...
          "Non-looping sound effect that will be played at the start of the explosion." );
       addField( "faceViewer", TypeBool, Offset(faceViewer, ExplosionData),
          "Controls whether the visual effects of the explosion always face the camera." );
       //yorks in ~line 300
       addField("faceZ", TypeBool, Offset(faceZ, ExplosionData),
    	   "Controls whether the visual effects of the explosion always face Z axis/up axis.\n\n"
    	   "Does not work with faceViewer as faceViewer takes precedent.");
       //yorks in end ~line 304
     
       addField( "particleEmitter", TYPEID< ParticleEmitterData >(), Offset(particleEmitter, ExplosionData),
    //...
     
    void ExplosionData::packData(BitStream* stream)
    {
    //...
       stream->write(particleRadius);
       stream->writeFlag(faceViewer);
       stream->writeFlag(faceZ);//yorks in ~line 559
       if(stream->writeFlag(explosionScale.x != 1 || explosionScale.y != 1 || explosionScale.z != 1))
    //...
     
    void ExplosionData::unpackData(BitStream* stream)
    {
    //...
       particleDensity = stream->readInt(14);
       stream->read(&particleRadius);
       faceViewer = stream->readFlag();
       faceZ = stream->readFlag();//yorks in ~line 666 MAIDEN MAIDEN :P
       if(stream->readFlag())
    //...
     
    //--------------------------------------------------------------------------
    // Make the explosion face the viewer (if desired)
    //--------------------------------------------------------------------------
    void Explosion::prepModelView(SceneRenderState* state)
    {
       MatrixF rotMatrix( true );
       Point3F targetVector;
     
       if( mDataBlock->faceViewer )
       {
          targetVector = getPosition() - state->getCameraPosition();
          targetVector.normalize();
     
          // rotate explosion each time so it's a little different
          rotMatrix.set( EulerF( 0.0f, mRandAngle, 0.0f ) );
       }
       /* //yorks out ~line 1039
       else
       {
    	  targetVector = mInitialNormal;//yorks out end
       }
       */ //yorks out end
       else if (mDataBlock->faceZ)//yorks new in ~line 1045
       {
    	  targetVector = state->getCameraPosition() - getPosition();
    	  targetVector.z = 0.0f;
    	  targetVector.normalize();
       }
       else
    	   targetVector = mInitialNormal;//yorks new end ~line 1052
     
       MatrixF explOrient = MathUtils::createOrientFromDir( targetVector );
       explOrient.mul( rotMatrix );
       explOrient.setPosition( getPosition() );
     
       setCurrentScale();
       explOrient.scale( mObjScale );
       GFX->setWorldMatrix( explOrient );
    }

     

    Note: In the above code faceZ is overriden if faceViewer is set to true.


    And in your explosion datablock add faceZ = true; to enable it.

     

    datablock ExplosionData(smallExplosion)
    {
       explosionShape = "art/shapes/yorks/mesh_explosions/distort_explo500.dts";//your animated mesh with z-axis for up
       faceZ = true;//no tilting!
     
       lifeTimeMS = 500; // Remember explosionShape Ambient animation length overrides this!!!
       lifetimeVariance = 0;
     
       // Point emission
       emitter[0] = smallDarkExpEmitter;
       emitter[1] = smallExpSparksEmitter;
       emitter[2] = smallExpDustEmitter;
    };

     

    Now if you want animated explosions to always face upright regardless of impact vector rotation - they will!

    :mrgreen:

  4. On @JeffR advice I added:

    mCastShadows = true;//yorks in (to customMaterialDefinition.cpp)

    bool mCastShadows;//yorks in (to customMaterialDefinition.h)

    virtual bool castsShadows() const { return mCastShadows; }//yorks in (to customMaterialDefinition.h)


    Okay, so what's happening now is this:

     

    // This is a custom material... who knows what it really does, but

    // if it wasn't already filtered out of the shadow render then just

    // give it some default depth out material.

     

    So now translucent gets filtered out and no shadows appear, and non-translucent customMaterials cast shadows - regardless of what castShadows=bool setting the texture material actually has.


    A more useful addition would be to get the status of castShadows and then force "shadowMat = MATMGR->getMaterialDefinitionByName( "AL_DefaultShadowMaterial" );" whether translucent or not. Though I'm not sure how to do that ... :|

  5. After much searching for shadows in customMaterials and shaders ... turns out I should have been looking for customMaterials in shadows ... :roll:


    lighting/shadowMap/shadowMatHook.cpp

     

    void ShadowMaterialHook::init( BaseMatInstance *inMat )
    {
    //...
       // Do instancing in shadows if we can.
       if ( inFeatures.hasFeature( MFT_UseInstancing ) )
          features.addFeature( MFT_UseInstancing );
     
       Material *shadowMat = (Material*)inMat->getMaterial();
       if ( dynamic_cast( shadowMat ) )
       {
          // This is a custom material... who knows what it really does, but
          // if it wasn't already filtered out of the shadow render then just
          // give it some default depth out material.
          //shadowMat = MATMGR->getMaterialDefinitionByName( "AL_DefaultShadowMaterial" );//<<<<<<<<<
       }
     
       // By default we want to disable some states
       // that the material might enable for us.
    //...

     

    So ends up being a standard Torque concept of "who knows what the hell this for, let's just do something with it" :lol:

  6. Anyone know how to disable a custom material/shader from casting shadows?


    I've looked through the stock hlsl files for reference and can find how to make it accept shadowing but aren't seeing anything it not casting shadows ...

  7. Well there is already support for baked shadows (lightmaps) per material using the toneMap (coloured lightmap) material slot. You just do the baking in a third party app like Blender or pureLight or whatever and make sure you export the model with the second UV unwrapped for the toneMap.


    Here's a pic in Torque editor:

    http://yorkshirerifles.com/random/tonemaptest.jpg


    here's an old in-game pic with no lights:

    http://farm5.static.flickr.com/4138/4871720090_136c4da402_b.jpg


    And here's an ancient level I made without any lights, just tonemaps:

    JfFsyRHm-Rg


    As for in-engine baked shadows, I think [mention]Azaezel[/mention] has been working on get lights to cast static shadows but I've been busy and not really kept up to date with what's going on with engine development lately.

  8. Done automatically now using the weaponImage datablock. So >>imageAnimPrefix = "Pistol";<< uses animations such as >>pistol_root.dsg<<, >>pistol_run.dsq<<, etc, etc.

    Not sure if it can be manually set for mounting objects eg: staticShapeData.

  9. Just skim read the thread but off my head ...

     

    Thanks for the caution. At the moment I am just using it for basic things such as opening doors etc.

     

    You could slap a trigger over the door area (making it larger so the player doesn't run into the door to have it operate) and have it operate that way with the trigger's onEnterTrigger function. Probably a good idea to have it contain a variable for open or shut (isOpen) and have the door object ID (doorID) given to the trigger. But the gist should be something like.

     

    function doorTrigger::onEnterTrigger(%this,%trigger,%obj)
    {
       %door = %trigger.doorID();
       if(%trigger.isOpen == false)
          if(%obj.getType() $="Player")//only players open doors, note AIPlayer derives from Player
             %door.playThread(0, "openDoor");//your animation for the door or call whatever function that opens it here
    }

     

    Alternatively you could have the player touch the door on the Player's OnCollision callback.

    function Player::onCollision(%this, %obj, %col)
    {
       // assuming door is staticObject
       if (%col.getType() & $TypeMasks::StaticObjectType)
       {
          %db = %col.getDataBlock();
          if (%db.getClassName() $= "DoorData" ) 
          {
             // Open door
             %col.playThread(0, "openDoor");//for animation or whatever function call to open door
          }
       }
    }

     

    Anyhow those or all things which can help reduce using looping schedules.

  10. I tested the release exe in the binaries and that gave confirmation of the crash, so at least I know it's not my building that's the issue here. So it looks like SDL bootstraps something to get OpenGL to work on my GPU (I'm guessing it's gpu?).


    Incidentally, whilst the most modern Nvidia driver is 368.81, the GTS 250 had it's driver updates discontinued at 341.95. Still doesn't explain working with SDL but not without it though. :x

  11. Downloaded VS2015Community.

    Successfully got it build and run in SDL debug.

    Still crashes in release at same place, so can't call a stack. :(


    Console log, seems same as before: http://pastebin.com/14RNUqQ7


    EDIT still does crash in non-SDL debug.

     

    Program shaders/common/fixedFunction/gl/textureV.glsl / shaders/common/fixedFunction/gl/textureP.glsl: 
    'OpenGL_DEBUG.exe' (Win32): Loaded 'C:\Windows\System32\dxva2.dll'. Cannot find or open the PDB file.
    OPENGL: GL_INVALID_OPERATION error generated. Invalid draw binding.
    Exception thrown at 0x0353FDE9 in OpenGL_DEBUG.exe: 0xC0000005: Access violation reading location 0x00000000.

     

    Stack looks the same as before.

    http://i.imgur.com/FeANlyh.png


    Just to note: running in SDL tilde/console is the "normal console key" under ESC on my non-US keyboard whilst non SDL (and all previous versions of T3D) it's the key that says tilde (next to return on UK keyboard layout).

  12. Not realizing openGL was going to available for windows (thought it was just for Linux) I never bothered testing the RC. But seeing that it was I eventually got CMake working with much help and gave it a whirl out of nothing more than curiousity ... and it crashes on startup.


    My ancient rig: core2, 3GB RAM, GTS 250 512mb DX10


    Splash screen shows, window with grey background appears, and then crash.


    Trying it with SDL was a pain because VS2013 Express doesn't have atlbase.h but eventually after many hours I found an old Win Driver Kit taht had it. Linking the includes and libs VS still couldn't bloody find the file so I just dumped the lot in VS12/VC/include and it finally compiled with SDL. Still crashes mind.


    New stuff on the console log:

     

    Program shaders/common/fixedFunction/gl/textureV.glsl / shaders/common/fixedFunction/gl/textureP.glsl: 
    'OpenGL_DEBUG.exe' (Win32): Loaded 'C:\Windows\System32\dxva2.dll'. Cannot find or open the PDB file.
    OPENGL: GL_INVALID_OPERATION error generated. Invalid draw binding.
    First-chance exception at 0x0085FD29 in OpenGL_DEBUG.exe: 0xC0000005: Access violation reading location 0x00000000.
    Unhandled exception at 0x0085FD29 in OpenGL_DEBUG.exe: 0xC0000005: Access violation reading location 0x00000000.

     

    Full log http://pastebin.com/AFy44YYt


    And the stack:

     

    0085fd29()	Unknown
     	[Frames below may be incorrect and/or missing]	
     	nvoglv32.dll!69331ede()	Unknown
     	nvoglv32.dll!6933020a()	Unknown
     	nvoglv32.dll!68b728e3()	Unknown
    >	OpenGL_DEBUG.exe!get_dispatch_table() Line 115020	C
     	OpenGL_DEBUG.exe!epoxy_glDrawArrays_dispatch_table_thunk(unsigned int mode, int first, int count) Line 109269	C
     	OpenGL_DEBUG.exe!GFXGLDevice::drawPrimitive(GFXPrimitiveType primType, unsigned int vertexStart, unsigned int primitiveCount) Line 599	C++
     	OpenGL_DEBUG.exe!GFXDrawUtil::drawBitmapStretchSR(GFXTextureObject * texture, const RectF & dstRect, const RectF & srcRect, const GFXBitmapFlip in_flip, const GFXTextureFilterType filter, bool in_wrap) Line 417	C++
     	OpenGL_DEBUG.exe!GFXDrawUtil::drawBitmapStretch(GFXTextureObject * texture, const RectF & dstRect, const GFXBitmapFlip in_flip, const GFXTextureFilterType filter, bool in_wrap) Line 342	C++
     	OpenGL_DEBUG.exe!GFXDrawUtil::drawBitmapStretch(GFXTextureObject * texture, const RectI & dstRect, const GFXBitmapFlip in_flip, const GFXTextureFilterType filter, bool in_wrap) Line 313	C++
     	OpenGL_DEBUG.exe!GuiBitmapCtrl::onRender(Point2I offset, const RectI & updateRect) Line 210	C++
     	OpenGL_DEBUG.exe!GuiFadeinBitmapCtrl::onRender(Point2I offset, const RectI & updateRect) Line 159	C++
     	OpenGL_DEBUG.exe!GuiCanvas::renderFrame(bool preRenderOnly, bool bufferSwap) Line 1858	C++
     	OpenGL_DEBUG.exe!GuiCanvas::handlePaintEvent(unsigned int did) Line 357	C++
     	OpenGL_DEBUG.exe!fastdelegate::FastDelegate1::operator()(unsigned int p1) Line 989	C++
     	OpenGL_DEBUG.exe!Signal::trigger(unsigned int a) Line 669	C++
     	OpenGL_DEBUG.exe!Journal::Call,unsigned int>(Signal * obj, void (unsigned int) * method, unsigned int a) Line 634	C++
     	OpenGL_DEBUG.exe!JournaledSignal::trigger(unsigned int a) Line 81	C++
     	OpenGL_DEBUG.exe!GuiCanvas::paint() Line 1588	C++
     	OpenGL_DEBUG.exe!fastdelegate::FastDelegate0::operator()() Line 904	C++
     	OpenGL_DEBUG.exe!Signal::trigger() Line 651	C++
     	OpenGL_DEBUG.exe!Process::processEvents() Line 101	C++
     	OpenGL_DEBUG.exe!StandardMainLoop::doMainLoop() Line 625	C++
     	OpenGL_DEBUG.exe!TorqueMain(int argc, const char * * argv) Line 315	C++
     	OpenGL_DEBUG.exe!run(int argc, const char * * argv) Line 337	C++
     	OpenGL_DEBUG.exe!WinMain(HINSTANCE__ * hInstance, HINSTANCE__ * __formal, char * lpszCmdLine, int __formal) Line 395	C++
     	[External Code]

     

    and in image format for easier reading:


    http://i.imgur.com/EqguXF1.png

    http://i.imgur.com/EqguXF1.png


    If this helps anyone ... :cry:

  13. Updated: Now (looping) emitters can be turned on/off via script with %emitter.setActive(%bool); and they'll immediately restart. 8-)


    I use some animated particles which generally have a high ejectionPeriodMS eg: 1000 = 1 particle per second. I didn't like waiting till the end of the time for the emitter to start up so I modded the code to "JumpStart" the process. It's especially useful when you've got an animated sprite sheet with a long ejectionPeriodMS that loops.


    New code:

    QuickStart var for emitterData so you can pick and choose the emitters for this to work on.

    mJumpStart bool to determine whether the emitter has already launched it's quickStarted.


    particleEmitter.h

    //...
    class ParticleEmitterData : public GameBaseData
    {
    //...
      public:
      //...
       bool glow;                                ///< Renders this emitter into the glow buffer.
     
       bool reload();
     
       bool QuickStart;//yorks new ~line 120
    };
     
    //... 
       bool mDead;
     
       bool mJumpStart;//yorks new ~line 193
     
      protected:
    //...

     

    particleEmitter.cpp

    //...
     
    void ParticleEmitterData::initPersistFields()
    {
    //...
     
    ParticleEmitterData::ParticleEmitterData()
    {
       VECTOR_SET_ASSOCIATION(particleDataBlocks);
    //...
       alignDirection = Point3F(0.0f, 1.0f, 0.0f);
     
       QuickStart = false;//yorks ~line 157
    }
     
    // Enum tables used for fields blendStyle, srcBlendFactor, dstBlendFactor.
     
    //...
       addGroup( "ParticleEmitterData" );
    //...
          addField("glow", TYPEID< bool >(), Offset(glow, ParticleEmitterData),
             "If true, the particles are rendered to the glow buffer as well.");
     
    	  //yorks new ~line 298
    	  addField("quickStart", TYPEID< bool >(), Offset(QuickStart, ParticleEmitterData),
    		  "If true, the first particle spawns immediately. " 
    		  "This overrides ejectionPeriodMS for the first particle only.");
     
          //@}
     
       endGroup( "ParticleEmitterData" );
     
       Parent::initPersistFields();
    }
     
    //... 
     
    ParticleEmitter::ParticleEmitter()
    {
       //...
       mDead = false;
       mDataBlock = NULL;
     
       mJumpStart = true;//yorks new ~line 755
     
       // ParticleEmitter should be allocated on the client only.
       mNetFlags.set( IsGhost );
    }
     
    //...
     
    void ParticleEmitter::emitParticles(const Point3F& start,
                                        const Point3F& end,
                                        const Point3F& axis,
                                        const Point3F& velocity,
                                        const U32      numMilliseconds)
    {
    //...
     
       U32 currTime = 0;
       bool particlesAdded = false;
     
       bool mQuick = mDataBlock->QuickStart;//yorks ~line 1050
     
       if (mQuick == true)
       {
    	   if (mJumpStart == true)//yorks new start
    	   {
    			//Con::printf("jumpstart");
    			mJumpStart = false;//let's not repeat when we don't need to jumpStart
    			mNextParticleTime = numMilliseconds;
    	   }//yorks new end
       }
     
       Point3F axisx;
       if( mFabs(axis.z) < 0.9f )
    //...
    }

     

    Next up we need to head over and make sure that mJumpStart resets when the emitter starts to replay.


    particleEmitterNode.cpp

    //...
    void ParticleEmitterNode::advanceTime(F32 dt)
    {
       Parent::advanceTime(dt);
     
       //yorks start ~line 289
       /*
       if (!mActive || mEmitter.isNull() || !mDataBlock)//yorks this out and changed below
          return;
    	 */
       if (mEmitter.isNull() || !mDataBlock)
    	   return;
     
       if (!mActive)
       {
    	   bool mEarly = mEmitterDatablock->QuickStart;
     
    	   if (mEarly == true)
    	   {
    		   bool mJump = mEmitter->mJumpStart;
    		   if (mJump == false)
    			   mEmitter->mJumpStart = true;
    	   }
    	   return;
       }//yorks end ~line 308
     
       Point3F emitPoint, emitVelocity;
       Point3F emitAxis(0, 0, 1);
       getTransform().mulV(emitAxis);
       getTransform().getColumn(3, &emitPoint);
       emitVelocity = emitAxis * mVelocity;
     
       mEmitter->emitParticles(emitPoint, emitPoint,
                               emitAxis,
    						   emitVelocity, (U32)(dt * mDataBlock->timeMultiple * 1000.0f));
    }
    //...

     

    Now to get it to go you just have to add "QuickStart = true" into your scripted ParticleEmitterData datablock.

    datablock ParticleEmitterData(circlesInLoopEmitter)
    {
       ejectionPeriodMS = "800";
       periodVarianceMS = "0";
     
       ejectionVelocity = "0";
       velocityVariance = "0";
       ejectionOffset   = "1";
     
       thetaMin         = "0";
       thetaMax         = "0";
     
       particles        = "circlesInLoopParticle";
       ejectionOffsetVariance = "0";
       blendStyle = "ADDITIVE";
       glow = "0";
       lifetimeMS = "0";
       alignParticles = "1";
       alignDirection = "0 0 1";
       phiVariance = "0";
     
       QuickStart = true;//yorks
    };

     

    And voila, maybe not the prettiest code 'cos mine never is, but it does seem to work nicely. ;)

    As ever, If anyone has a better way, feel free to pipe up. :D

×
×
  • Create New...