⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 splash.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 2 页
字号:
                             const U32 /*startZone*/, const bool /*modifyBaseState*/)
{
   if (isLastState(state, stateKey))
      return false;
   setLastState(state, stateKey);

   // This should be sufficient for most objects that don't manage zones, and
   //  don't need to return a specialized RenderImage...
   if (state->isObjectRendered(this)) 
   {
      mFog = 0.0;

      SceneRenderImage* image = new SceneRenderImage;
      image->obj = this;
      image->isTranslucent = true;
      image->sortType = SceneRenderImage::Point;
      image->textureSortKey = (U32)(dsize_t)mDataBlock;
      state->setImageRefPoint(this, image);
      state->insertRenderImage(image);
   }

   return false;
}

//--------------------------------------------------------------------------
// Render
//--------------------------------------------------------------------------
void Splash::renderObject(SceneState* state, SceneRenderImage*)
{
   AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");

   RectI viewport;
   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   dglGetViewport(&viewport);

   state->setupObjectProjection(this);

   render();

   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode(GL_MODELVIEW);
   dglSetViewport(viewport);

   AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
}

//--------------------------------------------------------------------------
// Process tick
//--------------------------------------------------------------------------
void Splash::processTick(const Move*)
{
   mCurrMS += TickMs;

#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsServerObject
   if( isServerObject() )
   {
      if( mCurrMS >= mEndingMS )
      {
         mDead = true;
         if( mCurrMS >= (mEndingMS + mDataBlock->ringLifetime * 1000) )
         {
            deleteObject();
         }
      }
   }
   else
#endif
   {
      if( mCurrMS >= mEndingMS )
      {
         mDead = true;
      }
   }
}

//--------------------------------------------------------------------------
// Advance time
//--------------------------------------------------------------------------
void Splash::advanceTime(F32 dt)
{
   if (dt == 0.0)
      return;

   mElapsedTime += dt;

   updateColor();
   updateWave( dt );
   updateEmitters( dt );
   updateRings( dt );

   if( !mDead )
   {
      emitRings( dt );
   }
}

//----------------------------------------------------------------------------
// Update emitters
//----------------------------------------------------------------------------
void Splash::updateEmitters( F32 dt )
{
   Point3F pos = getPosition();

   for( U32 i=0; i<SplashData::NUM_EMITTERS; i++ )
   {
      if( mEmitterList[i] )
      {
         mEmitterList[i]->emitParticles( pos, pos, mInitialNormal, Point3F( 0.0, 0.0, 0.0 ), (S32) (dt * 1000) );
      }
   }

}

//----------------------------------------------------------------------------
// Update wave
//----------------------------------------------------------------------------
void Splash::updateWave( F32 dt )
{
   mVelocity += mDataBlock->acceleration * dt;
   mRadius += mVelocity * dt;

}

//----------------------------------------------------------------------------
// Render splash
//----------------------------------------------------------------------------
void Splash::render()
{
   glDisable(GL_CULL_FACE);
   glDepthMask(GL_FALSE);
   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE);


   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
   glEnable(GL_TEXTURE_2D);


   SplashRing *ring = NULL;

   U32 i=0;
   while( bool( ring = ringList.next( ring ) ) )
   {
      SplashRing *next = ringList.next( ring );
      
      if( !next )
         break;

      renderSegment( *ring, *next );
      i++;
   }


   glDisable(GL_TEXTURE_2D);
   glDisable(GL_BLEND);
   glDepthMask(GL_TRUE);
   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}

//----------------------------------------------------------------------------
// Render horizontal segment created from 2 sets of points that are the
// top and bottom rings of the segment.
//----------------------------------------------------------------------------
void Splash::renderSegment( SplashRing &top, SplashRing &bottom )
{
   F32 texFactor = mDataBlock->texWrap;

   glBindTexture( GL_TEXTURE_2D, mDataBlock->textureHandle[0].getGLName() );

   F32 topAlpha = top.elapsedTime / top.lifetime;
   F32 bottomAlpha = bottom.elapsedTime / bottom.lifetime;

   if( topAlpha < 0.5 )
      topAlpha *= 2.0;
   else
      topAlpha = 1.0 - topAlpha;

   if( bottomAlpha < 0.5 )
      bottomAlpha *= 2.0;
   else
      bottomAlpha = 1.0 - bottomAlpha;

   top.color.alpha = topAlpha;
   bottom.color.alpha = bottomAlpha;


   glBegin( GL_QUAD_STRIP );
   {
      for( U32 i=0; i<top.points.size(); i++ )
      {
         F32 t = F32(i) / F32(top.points.size());

         glTexCoord2f( t * texFactor, top.v );
         glColor4fv( top.color );
         glVertex3fv( top.points[i].position );

         glTexCoord2f( t * texFactor, bottom.v );
         glColor4fv( bottom.color );
         glVertex3fv( bottom.points[i].position );
      }

      glTexCoord2f( 1.0 * texFactor, top.v );
      glColor4fv( top.color );
      glVertex3fv( top.points[0].position );

      glTexCoord2f( 1.0 * texFactor, bottom.v );
      glColor4fv( bottom.color );
      glVertex3fv( bottom.points[0].position );
   }
   glEnd();
}

//----------------------------------------------------------------------------
// Update color
//----------------------------------------------------------------------------
void Splash::updateColor()
{
   SplashRing *ring = NULL;

   while( bool( ring = ringList.next( ring ) ) )
   {
      F32 t = F32(ring->elapsedTime) / F32(ring->lifetime);

      for( U32 i = 1; i < SplashData::NUM_TIME_KEYS; i++ )
      {
         if( mDataBlock->times[i] >= t )
         {
            F32 firstPart =   t - mDataBlock->times[i-1];
            F32 total     =   (mDataBlock->times[i] -
                               mDataBlock->times[i-1]);

            firstPart /= total;

            ring->color.interpolate( mDataBlock->colors[i-1],
                                     mDataBlock->colors[i],
                                     firstPart);
            break;
         }
      }
   }
}

//----------------------------------------------------------------------------
// Create ring
//----------------------------------------------------------------------------
SplashRing Splash::createRing()
{
   SplashRing ring;
   U32 numPoints = mDataBlock->numSegments + 1;

   Point3F ejectionAxis( 0.0, 0.0, 1.0 );

   Point3F axisx;
   if (mFabs(ejectionAxis.z) < 0.999f)
      mCross(ejectionAxis, Point3F(0, 0, 1), &axisx);
   else
      mCross(ejectionAxis, Point3F(0, 1, 0), &axisx);
   axisx.normalize();

   for( U32 i=0; i<numPoints; i++ )
   {
      F32 t = F32(i) / F32(numPoints);

      AngAxisF thetaRot( axisx, mDataBlock->ejectionAngle * (M_PI / 180.0));
      AngAxisF phiRot(   ejectionAxis, t * (M_PI * 2.0));

      Point3F pointAxis = ejectionAxis;

      MatrixF temp;
      thetaRot.setMatrix(&temp);
      temp.mulP(pointAxis);
      phiRot.setMatrix(&temp);
      temp.mulP(pointAxis);

      Point3F startOffset = axisx;
      temp.mulV( startOffset );
      startOffset *= mDataBlock->startRadius;

      SplashRingPoint point;
      point.position = getPosition() + startOffset;
      point.velocity = pointAxis * mDataBlock->velocity;

      ring.points.push_back( point );
   }

   ring.color = mDataBlock->colors[0];
   ring.lifetime = mDataBlock->ringLifetime;
   ring.elapsedTime = 0.0;
   ring.v = mDataBlock->texFactor * mFmod( mElapsedTime, 1.0 );

   return ring;
}

//----------------------------------------------------------------------------
// Emit rings
//----------------------------------------------------------------------------
void Splash::emitRings( F32 dt )
{
   mTimeSinceLastRing += dt;

   S32 numNewRings = (S32) (mTimeSinceLastRing * F32(mDataBlock->ejectionFreq));

   mTimeSinceLastRing -= numNewRings / mDataBlock->ejectionFreq;

   for( S32 i=numNewRings-1; i>=0; i-- )
   {
      F32 t = F32(i) / F32(numNewRings);
      t *= dt;
      t += mTimeSinceLastRing;

      SplashRing ring = createRing();
      updateRing( &ring, t );

      ringList.link( ring );
   }
}

//----------------------------------------------------------------------------
// Update rings
//----------------------------------------------------------------------------
void Splash::updateRings( F32 dt )
{
   SplashRing *ring = NULL;
   while( bool( ring = ringList.next( ring ) ) )
   {
      ring->elapsedTime += dt;

      if( !ring->isActive() )
      {
         SplashRing *inactiveRing = ring;
         ring = ringList.prev( ring );
         ringList.free( inactiveRing );
      }
      else
      {
         updateRing( ring, dt );
      }
   }
}

//----------------------------------------------------------------------------
// Update ring
//----------------------------------------------------------------------------
void Splash::updateRing( SplashRing *ring, F32 dt )
{
   for( U32 i=0; i<ring->points.size(); i++ )
   {
      if( mDead )
      {
         Point3F vel = ring->points[i].velocity;
         vel.normalize();
         vel *= mDataBlock->acceleration;
         ring->points[i].velocity += vel * dt;
      }

      ring->points[i].velocity += Point3F( 0.0, 0.0, -9.8 ) * dt;
      ring->points[i].position += ring->points[i].velocity * dt;
   }
}

//----------------------------------------------------------------------------
// Explode
//----------------------------------------------------------------------------
void Splash::spawnExplosion()
{
   if( !mDataBlock->explosion ) return;

   Explosion* pExplosion = new Explosion;
   pExplosion->onNewDataBlock(mDataBlock->explosion);

   MatrixF trans = getTransform();
   trans.setPosition( getPosition() );

   pExplosion->setTransform( trans );
   pExplosion->setInitialState( trans.getPosition(), VectorF(0,0,1), 1);
   if (!pExplosion->registerObject())
      delete pExplosion;
}

//--------------------------------------------------------------------------
// packUpdate
//--------------------------------------------------------------------------
U32 Splash::packUpdate(NetConnection* con, U32 mask, BitStream* stream)
{
   U32 retMask = Parent::packUpdate(con, mask, stream);

   if( stream->writeFlag(mask & GameBase::InitialUpdateMask) )
   {
      mathWrite(*stream, mInitialPosition);
   }

   return retMask;
}

//--------------------------------------------------------------------------
// unpackUpdate
//--------------------------------------------------------------------------
void Splash::unpackUpdate(NetConnection* con, BitStream* stream)
{
   Parent::unpackUpdate(con, stream);

   if( stream->readFlag() )
   {
      mathRead(*stream, &mInitialPosition);
      setPosition( mInitialPosition );
   }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -