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

📄 lightning.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:

      pEvent->mStart.x = strikePoint.x;
      pEvent->mStart.y = strikePoint.y;
      pEvent->mTarget = targetObj;

      nc->postNetEvent(pEvent);
   }


}

//--------------------------------------------------------------------------
void Lightning::strikeObject(ShapeBase*)
{
   AssertFatal(isServerObject(), "Error, client objects may not initiate lightning!");

   AssertFatal(false, "Lightning::strikeObject is not implemented.");
}


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

   // Only write data if this is the initial packet or we've been inspected.
   if (stream->writeFlag(mask & (InitialUpdateMask | ExtendedInfoMask)))
   {
      // Initial update
      mathWrite(*stream, getPosition());
      mathWrite(*stream, mObjScale);

      stream->write(strikeWidth);
      stream->write(chanceToHitTarget);
      stream->write(strikeRadius);
      stream->write(boltStartRadius);
      stream->write(color.red);
      stream->write(color.green);
      stream->write(color.blue);
      stream->write(fadeColor.red);
      stream->write(fadeColor.green);
      stream->write(fadeColor.blue);
      stream->write(useFog);
      stream->write(strikesPerMinute);
   }

   return retMask;
}

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

   if (stream->readFlag())
   {
      // Initial update
      Point3F pos;
      mathRead(*stream, &pos);
      setPosition( pos );

      mathRead(*stream, &mObjScale);

      stream->read(&strikeWidth);
      stream->read(&chanceToHitTarget);
      stream->read(&strikeRadius);
      stream->read(&boltStartRadius);
      stream->read(&color.red);
      stream->read(&color.green);
      stream->read(&color.blue);
      stream->read(&fadeColor.red);
      stream->read(&fadeColor.green);
      stream->read(&fadeColor.blue);
      stream->read(&useFog);
      stream->read(&strikesPerMinute);
   }
}

//--------------------------------------------------------------------------
void Lightning::applyDamage( const Point3F& hitPosition,
                             const Point3F& hitNormal,
                             SceneObject*   hitObject)
{
#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   if (hitObject != NULL)
#else
   if (!isClientObject() && hitObject != NULL)
#endif
   {
      char *posArg = Con::getArgBuffer(64);
      char *normalArg = Con::getArgBuffer(64);

      dSprintf(posArg, 64, "%g %g %g", hitPosition.x, hitPosition.y, hitPosition.z);
      dSprintf(normalArg, 64, "%g %g %g", hitNormal.x, hitNormal.y, hitNormal.z);

      Con::executef(mDataBlock, 5, "applyDamage",
         Con::getIntArg(getId()),
         Con::getIntArg(hitObject->getId()),
         posArg,
         normalArg);
   }
}

//**************************************************************************
// Lightning Bolt
//**************************************************************************
LightningBolt::LightningBolt()
{
   width = 0.1;
   startPoint.zero();
   endPoint.zero();
   chanceOfSplit = 0.0;
   isFading = false;
   elapsedTime = 0.0;
   lifetime = 1.0;
   startRender = false;
}

//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
LightningBolt::~LightningBolt()
{
   splitList.free();
}

//--------------------------------------------------------------------------
// Generate nodes
//--------------------------------------------------------------------------
void LightningBolt::NodeManager::generateNodes()
{
   F32 overallDist = VectorF( endPoint - startPoint ).magnitudeSafe();
   F32 minDistBetweenNodes = overallDist / (numNodes-1);
   F32 maxDistBetweenNodes = minDistBetweenNodes / mCos( maxAngle * M_PI / 180.0 );

   VectorF mainLineDir = endPoint - startPoint;
   mainLineDir.normalizeSafe();

   for( U32 i=0; i<numNodes; i++ )
   {
      Node node;

      if( i == 0 )
      {
         node.point = startPoint;
         node.dirToMainLine = mainLineDir;
         nodeList[i] = node;
         continue;
      }
      if( i == numNodes - 1 )
      {
         node.point = endPoint;
         nodeList[i] = node;
         break;
      }

      Node lastNode = nodeList[i-1];

      F32 segmentLength = gRandGen.randF( minDistBetweenNodes, maxDistBetweenNodes );
      VectorF segmentDir = MathUtils::randomDir( lastNode.dirToMainLine, 0, maxAngle );
      node.point = lastNode.point + segmentDir * segmentLength;

      node.dirToMainLine = endPoint - node.point;
      node.dirToMainLine.normalizeSafe();
      nodeList[i] = node;
   }
}


//--------------------------------------------------------------------------
// Render bolt
//--------------------------------------------------------------------------
void LightningBolt::render( const Point3F &camPos )
{
   if( !startRender )
   {
      return;
   }

   if( !isFading )
   {
      generateMinorNodes();
   }

   glBegin( GL_TRIANGLE_STRIP );

   U32 i;
   for( i=0; i<mMinorNodes.size(); i++ )
   {
      if( i+1 == mMinorNodes.size() )
      {
         renderSegment( mMinorNodes[i], camPos, true );
      }
      else
      {
         renderSegment( mMinorNodes[i], camPos, false );
      }
   }

   glEnd();


   LightningBolt *curBolt = NULL;
   for( curBolt = splitList.next( curBolt ); curBolt; curBolt = splitList.next( curBolt ) )
   {
      if( isFading )
      {
         curBolt->isFading = true;
      }
      curBolt->render( camPos );
   }


}

//--------------------------------------------------------------------------
// Render segment
//--------------------------------------------------------------------------
void LightningBolt::renderSegment( NodeManager &segment, const Point3F &camPos, bool renderLastPoint )
{
   F32 totalLen = 0;
   for( int i=0; i<segment.numNodes; i++ )
   {
      Point3F  curPoint = segment.nodeList[i].point;

      Point3F  nextPoint;
      Point3F  segDir;

      if( i == (segment.numNodes-1) )
      {
         if( renderLastPoint )
         {
            segDir = curPoint - segment.nodeList[i-1].point;
         }
         else
         {
            continue;
         }
      }
      else
      {
         nextPoint = segment.nodeList[i+1].point;
         segDir = nextPoint - curPoint;
      }
      totalLen = segDir.len();
      segDir.normalizeSafe();


      Point3F dirFromCam = curPoint - camPos;
      Point3F crossVec;
      mCross(dirFromCam, segDir, &crossVec);
      crossVec.normalize();
      crossVec *= width * 0.5;

      glTexCoord2f( i, 1.0 );
      glVertex3fv( curPoint - crossVec );

      glTexCoord2f( i, 0.0 );
      glVertex3fv( curPoint + crossVec );
   }

}

//----------------------------------------------------------------------------
// Find height
//----------------------------------------------------------------------------
F32 LightningBolt::findHeight( Point3F &point, SceneGraph *sceneManager )
{
   TerrainBlock* pTerrain = sceneManager->getCurrentTerrain();
   if( !pTerrain ) return 0.0;

   Point3F terrPt = point;
   pTerrain->getWorldTransform().mulP(terrPt);
   F32 h;
   if (pTerrain->getHeight(Point2F(terrPt.x, terrPt.y), &h))
   {
      return h;
   }


   return 0.0;
}


//----------------------------------------------------------------------------
// Generate lightning bolt
//----------------------------------------------------------------------------
void LightningBolt::generate()
{
   mMajorNodes.startPoint   = startPoint;
   mMajorNodes.endPoint     = endPoint;
   mMajorNodes.numNodes     = numMajorNodes;
   mMajorNodes.maxAngle     = maxMajorAngle;

   mMajorNodes.generateNodes();

   generateMinorNodes();

}

//----------------------------------------------------------------------------
// Generate Minor Nodes
//----------------------------------------------------------------------------
void LightningBolt::generateMinorNodes()
{
   mMinorNodes.clear();

   for( int i=0; i<mMajorNodes.numNodes - 1; i++ )
   {
      NodeManager segment;
      segment.startPoint = mMajorNodes.nodeList[i].point;
      segment.endPoint = mMajorNodes.nodeList[i+1].point;
      segment.numNodes = numMinorNodes;
      segment.maxAngle = maxMinorAngle;
      segment.generateNodes();

      mMinorNodes.increment(1);
      mMinorNodes[i] = segment;
   }
}

//----------------------------------------------------------------------------
// Recursive algo to create bolts that split off from main bolt
//----------------------------------------------------------------------------
void LightningBolt::createSplit( Point3F startPoint, Point3F endPoint, U32 depth, F32 width )
{
   if( depth == 0 ) return;
   F32 chanceToEnd = gRandGen.randF();
   if( chanceToEnd > 0.70 ) return;

   if( width < 0.75 ) width = 0.75;

   VectorF diff = endPoint - startPoint;
   F32 length = diff.len();
   diff.normalizeSafe();

   LightningBolt newBolt;
   newBolt.startPoint = startPoint;
   newBolt.endPoint = endPoint;
   newBolt.width = width;
   newBolt.numMajorNodes = 3;
   newBolt.maxMajorAngle = 30;
   newBolt.numMinorNodes = 3;
   newBolt.maxMinorAngle = 10;
   newBolt.startRender = true;
   newBolt.generate();

   splitList.link( newBolt );

   VectorF newDir1 = MathUtils::randomDir( diff, 10.0, 45.0 );
   Point3F newEndPoint1 = endPoint + newDir1 * gRandGen.randF( 0.5, 1.5 ) * length;

   VectorF newDir2 = MathUtils::randomDir( diff, 10.0, 45.0 );
   Point3F newEndPoint2 = endPoint + newDir2 * gRandGen.randF( 0.5, 1.5 ) * length;

   createSplit( endPoint, newEndPoint1, depth - 1, width * 0.30 );
   createSplit( endPoint, newEndPoint2, depth - 1, width * 0.30 );

}

//----------------------------------------------------------------------------
// Start split - kick off the recursive 'createSplit' procedure
//----------------------------------------------------------------------------
void LightningBolt::startSplits()
{

   for( U32 i=0; i<mMajorNodes.numNodes-1; i++ )
   {
      if( gRandGen.randF() > 0.3 ) continue;

      Node node = mMajorNodes.nodeList[i];
      Node node2 = mMajorNodes.nodeList[i+1];

      VectorF segDir = node2.point - node.point;
      F32 length = segDir.len();
      segDir.normalizeSafe();

      VectorF newDir = MathUtils::randomDir( segDir, 20.0, 40.0 );
      Point3F newEndPoint = node.point + newDir * gRandGen.randF( 0.5, 1.5 ) * length;


      createSplit( node.point, newEndPoint, 4, width * 0.30 );
   }


}

//----------------------------------------------------------------------------
// Update
//----------------------------------------------------------------------------
void LightningBolt::update( F32 dt )
{
   elapsedTime += dt;

   F32 percentDone = elapsedTime / lifetime;

   if( elapsedTime > fadeTime )
   {
      isFading = true;
      percentFade = percentDone + (fadeTime/lifetime);
   }

   if( elapsedTime > renderTime && !startRender )
   {
      startRender = true;
      isFading = false;
      elapsedTime = 0.0;
   }
}

⌨️ 快捷键说明

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