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

📄 weatherlightning.cpp

📁 五行MMORPG引擎系统V1.0
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   
      // setup alpha value
      F32 strikeAlpha;
      if(currentAge < (strikeTime / 3.0))
      {
         strikeAlpha = currentAge / (strikeTime / 3.0);
         strikeAlpha = mPow(strikeAlpha, F32(1.0 / 3.0));
      }
      else if(currentAge < (2.0 * strikeTime / 3.0))
         strikeAlpha = 1.0;
      else
         strikeAlpha = 1.0 - ((currentAge - (2.0 * strikeTime / 3.0)) / (strikeTime / 3.0));
      glColor4f(1.0f, 1.0f, 1.0f, strikeAlpha);
      
      // generate texture coords
      Point3F points[4];
      F32 width = ((startPoint.z - endPoint.z) * 0.125f);
      points[0] = startPoint - perpVec * width;
      points[1] = startPoint + perpVec * width;
      points[2] = endPoint   + perpVec * width;
      points[3] = endPoint   - perpVec * width;
      
      // bind and draw texture
      glBindTexture(GL_TEXTURE_2D, strikeTexture->getGLName());
      glBegin(GL_TRIANGLE_FAN);
         glTexCoord2f(0, 0); glVertex3fv(points[0]);
         glTexCoord2f(0, 1); glVertex3fv(points[1]);
         glTexCoord2f(1, 1); glVertex3fv(points[2]);
         glTexCoord2f(1, 0); glVertex3fv(points[3]);
         //glTexCoord2f(0, 0); glVertex3fv(points[0]);
         //glTexCoord2f(1, 0); glVertex3fv(points[1]);
         //glTexCoord2f(1, 1); glVertex3fv(points[2]);
         //glTexCoord2f(0, 1); glVertex3fv(points[3]);
      glEnd();
   
   //
   // fuzzy texture
   //
   
      // setup alpha value
      F32 constAlpha;
      if(currentAge < strikeTime / 2.0)
         constAlpha = currentAge / (strikeTime / 2.0);
      else if(currentAge < (2.0 * strikeTime / 3.0))
         constAlpha = 1.0 - ((currentAge - (strikeTime / 2.0)) / (strikeTime / 6.0));
      else
         constAlpha = 0.0;
      glColor4f(1.0, 1.0, 1.0, constAlpha);
      
      // generate texture coords
      width *= 4;
      points[0] = startPoint - perpVec * width;
      points[1] = startPoint + perpVec * width;
      points[2] = endPoint   + perpVec * width;
      points[3] = endPoint   - perpVec * width;
      
      if(constAlpha != 0.0)
      {
         // bind and draw texture
         glBindTexture(GL_TEXTURE_2D, fuzzyTexture->getGLName());
         glBegin(GL_TRIANGLE_FAN);
            glTexCoord2f(0, 0); glVertex3fv(points[0]);
            glTexCoord2f(0, 1); glVertex3fv(points[1]);
            glTexCoord2f(1, 1); glVertex3fv(points[2]);
            glTexCoord2f(1, 0); glVertex3fv(points[3]);
            //glTexCoord2f(0, 0); glVertex3fv(points[0]);
            //glTexCoord2f(1, 0); glVertex3fv(points[1]);
            //glTexCoord2f(1, 1); glVertex3fv(points[2]);
            //glTexCoord2f(0, 1); glVertex3fv(points[3]);
         glEnd();
         
         glDepthMask(GL_TRUE);
      }
   
   //
   // flash texture
   //
   
      // setup alpha value
      glColor4f(1.0f, 1.0f, 1.0f, strikeAlpha);
      
      // generate texture coords
      points[0] = startPoint - perpVec * width + frontVec * width;
      points[1] = startPoint - perpVec * width - frontVec * width;
      points[2] = startPoint + perpVec * width - frontVec * width;
      points[3] = startPoint + perpVec * width + frontVec * width;

      // bind and draw texture
      glBindTexture(GL_TEXTURE_2D, flashTexture->getGLName());
      glBegin(GL_TRIANGLE_FAN);
         glTexCoord2f(0, 0); glVertex3fv(points[0]);
         glTexCoord2f(0, 1); glVertex3fv(points[1]);
         glTexCoord2f(1, 1); glVertex3fv(points[2]);
         glTexCoord2f(1, 0); glVertex3fv(points[3]);
         //glTexCoord2f(0, 0); glVertex3fv(points[0]);
         //glTexCoord2f(1, 0); glVertex3fv(points[1]);
         //glTexCoord2f(1, 1); glVertex3fv(points[2]);
         //glTexCoord2f(0, 1); glVertex3fv(points[3]);
      glEnd();
      
   //
   // finished
   //
   glDepthMask(GL_TRUE);
}

void WeatherLightning::renderObject(SceneState* state, SceneRenderImage*)
{
   if(mActiveBolts.size())
   {
      AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");

      RectI viewport;
      F64 farPlane;
      
      glMatrixMode(GL_PROJECTION);
      glPushMatrix();
      
      dglGetViewport(&viewport);
      farPlane = state->getFarPlane();
      const Point3F &camPos = state->getCameraPosition();
    
      // adjust far clip plane
      F64 distance = (getPosition() - camPos).lenSquared();
      state->setFarPlane(getMax(farPlane, distance));
      
      state->setupObjectProjection(this);

      glDisable(GL_CULL_FACE);
      glEnable(GL_TEXTURE_2D);
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
         
      for(U32 i = 0; i < mActiveBolts.size(); i++)
         mActiveBolts[i]->render(camPos);

      glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
      glDisable(GL_BLEND);
      glDisable(GL_TEXTURE_2D);

      glMatrixMode(GL_PROJECTION);
      glPopMatrix();
      glMatrixMode(GL_MODELVIEW);
      
      state->setFarPlane(farPlane);
      dglSetViewport(viewport);

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

void WeatherLightning::processTick(const Move *move)
{
   Parent::processTick(move);
   
   if (isServerObject()) 
   {
      S32 msBetweenStrikes = (S32)(60.0 / strikesPerMinute * 1000.0);
      
      lastThink += TickMs;
      if( lastThink > msBetweenStrikes )
      {
         strikeRandomPoint();
         lastThink -= msBetweenStrikes;
      }
   }
}

void WeatherLightning::advanceTime(F32 dt)
{
   Parent::advanceTime(dt);
   
   U32 i;
   
   // loop through and erase any dead bolts
   for(i = 0; i < mActiveBolts.size();)
   {
      WeatherLightningBolt* bolt = mActiveBolts[i];
      bolt->currentAge += dt;
      if(bolt->currentAge > bolt->deathAge)
      {
         delete bolt;
         mActiveBolts.erase_fast(i);
         continue;
      }
      
      i++;
   }
   
   // loop through and find any pending sound events
   for(i = 0; i < mSoundEvents.size();)
   {
      SoundEvent *sEvent = &mSoundEvents[i];
      sEvent->time -= dt;
      if(sEvent->time <= 0.0)
      {
         // fire off the sound
         if(sEvent->soundBlockId != -1)
            alxPlay(mDataBlock->thunderSounds[sEvent->soundBlockId], &sEvent->position);
         mSoundEvents.erase_fast(i);
         continue;
      }
      
      i++;
   } 
}

void WeatherLightning::strikeRandomPoint()
{  
   // choose random strike point within object bounds
   Point2F strikePoint;
   strikePoint.x = sgRandomGen.randF( 0.0, 1.0 );
   strikePoint.y = sgRandomGen.randF( 0.0, 1.0 );
   
   SimGroup* pClientGroup = Sim::getClientGroup();
   for (SimGroup::iterator itr = pClientGroup->begin(); itr != pClientGroup->end(); itr++)
   {
      NetConnection* nc = static_cast<NetConnection*>(*itr);

      WeatherLightningStrikeEvent* wlEvent = new WeatherLightningStrikeEvent;
      wlEvent->mLightning = this;
      wlEvent->mStart = strikePoint;

      nc->postNetEvent(wlEvent);
   }
}

TextureHandle* WeatherLightning::getRandomStrike()
{
   U32 strike = (U32)(mCeil(mDataBlock->numStrikes * sgRandomGen.randF()) - 1.0f);
   return &mDataBlock->strikeTextures[strike]; 
}

TextureHandle* WeatherLightning::getRandomFlash()
{
   U32 flash = (U32)(mCeil(mDataBlock->numFlashes * sgRandomGen.randF()) - 1.0f);
   return &mDataBlock->flashTextures[flash];
}

TextureHandle* WeatherLightning::getRandomFuzzy()
{
   U32 fuzzy = (U32)(mCeil(mDataBlock->numFuzzes * sgRandomGen.randF()) - 1.0f);
   return &mDataBlock->fuzzyTextures[fuzzy];
}

S32 WeatherLightning::getRandomSound()
{
   U32 sound = (U32)(mCeil(mDataBlock->numSounds * sgRandomGen.randF()) - 1.0f);
   if(mDataBlock->thunderSounds[sound] != NULL_AUDIOHANDLE)
      return sound;
   
   return -1;
}

void WeatherLightning::processEvent(WeatherLightningStrikeEvent* wlEvent)
{
   AssertFatal(wlEvent->mStart.x >= 0 && wlEvent->mStart.x <= 1.0, "Out of bounds coord!");

   mActiveBolts.push_back(new WeatherLightningBolt);
   WeatherLightningBolt* bolt = mActiveBolts.last();
   
   Point3F strikePoint(0.0, 0.0, 0.0);
   strikePoint.x = wlEvent->mStart.x;
   strikePoint.y = wlEvent->mStart.y;
   strikePoint *= mObjScale;
   strikePoint += getPosition();
   strikePoint += Point3F( -mObjScale.x * 0.5, -mObjScale.y * 0.5, 0.0 );

   RayInfo rayInfo;
   Point3F start = strikePoint;
   start.z = mObjScale.z * 0.5 + getPosition().z;
   strikePoint.z += -mObjScale.z * 0.5;
   bool rayHit = gClientContainer.castRay(start, strikePoint, (STATIC_COLLISION_MASK | WaterObjectType), &rayInfo);
   if(rayHit)
      strikePoint.z = rayInfo.point.z;
   
   F32 height = mObjScale.z * 0.5 + getPosition().z;
   
   bolt->startPoint = Point3F(strikePoint.x, strikePoint.y, height);
   bolt->endPoint   = strikePoint;
   
   bolt->currentAge       = 0.0f;
   bolt->deathAge         = boltDeathAge;
   bolt->strikeTime       = 0.35;
   
   bolt->strikeTexture = getRandomStrike();
   bolt->flashTexture  = getRandomFlash();
   bolt->fuzzyTexture  = getRandomFuzzy();
   
   // setup a thunder sound event
   Point3F listener;
   alxGetListenerPoint3F(AL_POSITION, &listener);
   
   mSoundEvents.increment();
   SoundEvent& sEvent = mSoundEvents.last();
   
   // find the length to the closest point on the bolt
   Point3F dHat = bolt->startPoint - bolt->endPoint;
   F32 boltLength = dHat.len();
   dHat /= boltLength;
   F32 distAlong = mDot((listener - bolt->endPoint), dHat);
   
   Point3F contactPoint;
   if(distAlong >= boltLength)
      contactPoint = bolt->startPoint;
   else if(distAlong <= 0.0)
      contactPoint = bolt->endPoint;
   else
      contactPoint = bolt->endPoint + dHat * distAlong;
      
   F32 delayDist = (listener - contactPoint).len();
   U32 delayTime = U32((delayDist / 330.0f) * 100.0f);
   
   MatrixF trans(true);
   trans.setPosition(contactPoint);
   
   sEvent.soundBlockId = getRandomSound();
   sEvent.position = trans;
   sEvent.time = delayTime;
   
   // play strike sound
   trans.setPosition(strikePoint);
   if(mDataBlock->strikeSound)
      alxPlay(mDataBlock->strikeSound, &trans);
}

U32 WeatherLightning::packUpdate(NetConnection *conn, U32 mask, BitStream *stream)
{
   U32 retMask = Parent::packUpdate(conn, 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);
   }

   return retMask;
}

void WeatherLightning::unpackUpdate(NetConnection *conn, BitStream *stream)
{
   Parent::unpackUpdate(conn, stream);

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

      mathRead(*stream, &mObjScale);
   }
}

⌨️ 快捷键说明

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