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

📄 shapebase.cc

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





#ifdef TGE_RPG	/// TGE_Move

void ShapeBase::getCameraTransform(F32* pos,MatrixF* mat)
{
	Point3F camVec(-10,-10,20),posLookAt;
	MatrixF sRPGTran;

	//Con::warnf("%f %f %f",ms_fCameraPitch,ms_fCameraYaw,ms_fCameraDist);
   m_rotCamera.x += ms_fCameraPitch;
	m_rotCamera.x  = mClampF(m_rotCamera.x ,ms_fCameraMinPitch,ms_fCameraMaxPitch) ;
   m_rotCamera.z += ms_fCameraYaw;
   m_rotCamera.z  = mFmod(m_rotCamera.z, 360.f);
	m_fCameraDist += ms_fCameraDist;
	m_fCameraDist  = mClampF(m_fCameraDist, mDataBlock->cameraMinDist, mDataBlock->cameraMaxDist);

	ms_fCameraPitch	= 0;
	ms_fCameraYaw		= 0;
	ms_fCameraDist		= 0;

	F32 fPitch	=  m_rotCamera.x * M_PI_DIV180;
	F32 fYaw		=  m_rotCamera.z * M_PI_DIV180;
	//计算Camera -> lookat
	F32 fReflect = m_fCameraDist * mCos(fPitch);
	camVec.z		= m_fCameraDist * mSin(fPitch);
	camVec.x		= fReflect * mCos(fYaw);
	camVec.y		= fReflect * mSin(fYaw);

	//记得取负,相当于 0 -> camVec,这便是我们需要的矢量
	camVec.neg();


	/////////////////////////////////////////////
	///先获得人物依附的Cam节点位置,这是相机的焦点
	posLookAt = getRenderPosition();
	Point3F camPos = posLookAt - camVec;

	/// 检测camPos -> posLookAt之间是否有视线障碍,只处理以几类:
	/// 室内建筑、地形、水面;其它的不作处理(如人物模型、静态等)

	RayInfo collision;

	/// 从视点处,投射光线,检测是否有障碍物
	//// 暂时不作TerrainObjectType检测,移动时会引起画面闪烁;可以考虑静止时作处理
   if (mContainer->castRay(posLookAt,camPos, 
                           (WaterObjectType | /*TerrainObjectType |*/InteriorObjectType),
                           &collision) == true) 
	{

		/// 视线被地面挡住时,视线每5度地抬起来,直到没有交叉
		if(collision.object->getTypeMask() & TerrainObjectType )
		{

			//ms_fCameraDist
			MatrixF idMtx(true);
			VectorF x,y(camVec),z(0,0,1);
			y.normalize();
			mCross(y, z, &x);
			x.normalize();
			mCross(x, y, &z);
			z.normalize();

			idMtx.setColumn(0,x);
			idMtx.setColumn(1,y);
			idMtx.setColumn(2,z);

			/// 需要确定递增方向,还没找到公式
			F32 fDot = mDot(camVec,collision.normal);
			F32 fDiv = (fDot > 0.f)? M_PI_DIV180 : -M_PI_DIV180;

			RayInfo collision2;
			for(S32 n=1; n<90; n+=5)
			{
				MatrixF rotMtx( EulerF((float)n * fDiv,0.f,0.f) );
				rotMtx.mul(idMtx);
				VectorF camVec2;
				rotMtx.getColumn(1,&camVec2);
				camVec2 *= m_fCameraDist;

				Point3F camPos2 = posLookAt - camVec2;
				if (mContainer->castRay(camPos2, posLookAt, TerrainObjectType,&collision2) == false) 
				{
					camVec = camVec2;
					camPos = camPos2;
					break;
				}
			}

			//RayInfo collision2;
			//if (mContainer->castRay(camPos, posLookAt, TerrainObjectType,&collision2) == true) 
			//{
			//	if(collision2.t < 0.2f || collision.t < 0.2f || collision2.t + collision.t > 0.95)
			//	{
			//		MatrixF eye;
			//		getRenderEyeTransform(&eye);
			//		eye.getColumn(3,&posLookAt);
			//		camPos = posLookAt - 0.2f*camVec;
			//	}
			//	else
			//		camPos = posLookAt - (collision.t*0.90f)*camVec;
			//}
		}//TerrainObjectType

		else if(collision.object->getTypeMask() & InteriorObjectType )
		{
			/// 如果是室内建筑的话,视线障碍距离小于0.1,则把相机放在头部上
			/// 然后只要向前走,视线障碍距离collision.t越来越大时,
			/// 视点须由头部慢慢地下降过渡到脚中心 通过collision.t*LookAt2eye实现
			Point3F eyePos,LookAt2eye;
			MatrixF eye;
			getRenderEyeTransform(&eye);
			eye.getColumn(3,&eyePos);
			
			if(collision.t < 0.1f)
			{	
				camPos = eyePos;
				posLookAt = eyePos + (0.1f-collision.t)*0.90f*camVec;
			}
			else
			{
				LookAt2eye	= posLookAt- eyePos;
				posLookAt	= eyePos + collision.t*LookAt2eye;
				camPos		= posLookAt - (collision.t*0.95f)*camVec;
			}
		}//InteriorObjectType

		else if(collision.object->getTypeMask() &  WaterObjectType)
		{
			/// 浸水越深,相机距离拉得越近,离水面越近,视点越靠近头部,否则靠近脚中心
			Point3F eyePos,LookAt2eye;
			MatrixF eye;
			getRenderEyeTransform(&eye);
			eye.getColumn(3,&eyePos);
			LookAt2eye	= posLookAt- eyePos;

			if(mWaterCoverage < 0.9)
			{
				posLookAt	= posLookAt  -collision.t*LookAt2eye;
				camPos = posLookAt - (1.0f-collision.t)*camVec;
			}
			else 
			{
				posLookAt	= eyePos + collision.t*LookAt2eye;
				camPos		= posLookAt - (collision.t*0.90f)*camVec;
				//camPos = posLookAt - (collision.t*0.75f)*camVec;
			}

		}//WaterObjectType
	}





	//////////////////////////////////////////
	//依据 Camera -> lookat 矢量,建立相应的相机矩阵,相机焦点对准人物

	//1.假定y为Camera -> lookat矢量,z向上,计算此两矢量平面的单位法线(x轴)
	//2.依据x、y计算单位z轴
   VectorF x,y(camVec),z(0,0,1);
	y.normalize();
   mCross(y, z, &x);
   x.normalize();
   mCross(x, y, &z);
   z.normalize();

	mat->identity();
   mat->setColumn(0,x);
   mat->setColumn(1,y);
   mat->setColumn(2,z);

	mat->setColumn(3,camPos);

}


#else



void ShapeBase::getCameraTransform(F32* pos,MatrixF* mat)
{
   // Returns camera to world space transform
   // Handles first person / third person camera position

   if (isServerObject() && mShapeInstance)
      mShapeInstance->animateNodeSubtrees(true);

   if (*pos != 0)
   {
      F32 min,max;
      Point3F offset;
      MatrixF eye,rot;
      getCameraParameters(&min,&max,&offset,&rot);
      getRenderEyeTransform(&eye);
      mat->mul(eye,rot);

      // Use the eye transform to orient the camera
      VectorF vp,vec;
      vp.x = vp.z = 0;
      vp.y = -(max - min) * *pos;
      eye.mulV(vp,&vec);

      // Use the camera node's pos.
      Point3F osp,sp;
      if (mDataBlock->cameraNode != -1) {
         mShapeInstance->mNodeTransforms[mDataBlock->cameraNode].getColumn(3,&osp);

         // Scale the camera position before applying the transform
         const Point3F& scale = getScale();
         osp.convolve( scale );

         getRenderTransform().mulP(osp,&sp);
      }
      else
         getRenderTransform().getColumn(3,&sp);

      // Make sure we don't extend the camera into anything solid
      Point3F ep = sp + vec + offset;
      disableCollision();
      if (isMounted())
         getObjectMount()->disableCollision();
      RayInfo collision;
      if (mContainer->castRay(sp, ep,
                              (0xFFFFFFFF & ~(WaterObjectType      |
                                              GameBaseObjectType   |
                                              DefaultObjectType)),
                              &collision) == true) {
         F32 veclen = vec.len();
         F32 adj = (-mDot(vec, collision.normal) / veclen) * 0.1;
         F32 newPos = getMax(0.0f, collision.t - adj);
         if (newPos == 0.0f)
            eye.getColumn(3,&ep);
         else
            ep = sp + offset + (vec * newPos);
      }
      mat->setColumn(3,ep);
      if (isMounted())
         getObjectMount()->enableCollision();
      enableCollision();
   }
   else
   {
      getRenderEyeTransform(mat);
   }
}

#endif


// void ShapeBase::getCameraTransform(F32* pos,MatrixF* mat)
// {
//    // Returns camera to world space transform
//    // Handles first person / third person camera position

//    if (isServerObject() && mShapeInstance)
//       mShapeInstance->animateNodeSubtrees(true);

//    if (*pos != 0) {
//       F32 min,max;
//       Point3F offset;
//       MatrixF eye,rot;
//       getCameraParameters(&min,&max,&offset,&rot);
//       getRenderEyeTransform(&eye);
//       mat->mul(eye,rot);

//       // Use the eye transform to orient the camera
//       VectorF vp,vec;
//       vp.x = vp.z = 0;
//       vp.y = -(max - min) * *pos;
//       eye.mulV(vp,&vec);

//       // Use the camera node's pos.
//       Point3F osp,sp;
//       if (mDataBlock->cameraNode != -1) {
//          mShapeInstance->mNodeTransforms[mDataBlock->cameraNode].getColumn(3,&osp);
//          getRenderTransform().mulP(osp,&sp);
//       }
//       else
//          getRenderTransform().getColumn(3,&sp);

//       // Make sure we don't extend the camera into anything solid
//       Point3F ep = sp + vec;
//       ep += offset;
//       disableCollision();
//       if (isMounted())
//          getObjectMount()->disableCollision();
//       RayInfo collision;
//       if (mContainer->castRay(sp,ep,(0xFFFFFFFF & ~(WaterObjectType|ForceFieldObjectType|GameBaseObjectType|DefaultObjectType)),&collision)) {
//          *pos = collision.t *= 0.9;
//          if (*pos == 0)
//             eye.getColumn(3,&ep);
//          else
//             ep = sp + vec * *pos;
//       }
//       mat->setColumn(3,ep);
//       if (isMounted())
//          getObjectMount()->enableCollision();
//       enableCollision();
//    }
//    else
//    {
//       getRenderEyeTransform(mat);
//    }
// }


// void ShapeBase::getRenderCameraTransform(F32* pos,MatrixF* mat)
// {
//    // Returns camera to world space transform
//    // Handles first person / third person camera position

//    if (isServerObject() && mShapeInstance)
//       mShapeInstance->animateNodeSubtrees(true);

//    if (*pos != 0) {
//       F32 min,max;
//       Point3F offset;
//       MatrixF eye,rot;
//       getCameraParameters(&min,&max,&offset,&rot);
//       getRenderEyeTransform(&eye);
//       mat->mul(eye,rot);

//       // Use the eye transform to orient the camera
//       VectorF vp,vec;
//       vp.x = vp.z = 0;
//       vp.y = -(max - min) * *pos;
//       eye.mulV(vp,&vec);

//       // Use the camera node's pos.
//       Point3F osp,sp;
//       if (mDataBlock->cameraNode != -1) {
//          mShapeInstance->mNodeTransforms[mDataBlock->cameraNode].getColumn(3,&osp);
//          getRenderTransform().mulP(osp,&sp);
//       }
//       else
//          getRenderTransform().getColumn(3,&sp);

//       // Make sure we don't extend the camera into anything solid
//       Point3F ep = sp + vec;
//       ep += offset;
//       disableCollision();
//       if (isMounted())
//          getObjectMount()->disableCollision();
//       RayInfo collision;
//       if (mContainer->castRay(sp,ep,(0xFFFFFFFF & ~(WaterObjectType|ForceFieldObjectType|GameBaseObjectType|DefaultObjectType)),&collision)) {
//          *pos = collision.t *= 0.9;
//          if (*pos == 0)
//             eye.getColumn(3,&ep);
//          else
//             ep = sp + vec * *pos;
//       }
//       mat->setColumn(3,ep);
//       if (isMounted())
//          getObjectMount()->enableCollision();
//       enableCollision();
//    }
//    else
//    {
//       getRenderEyeTransform(mat);
//    }
// }

void ShapeBase::getCameraParameters(F32 *min,F32* max,Point3F* off,MatrixF* rot)
{
   *min = mDataBlock->cameraMinDist;
   *max = mDataBlock->cameraMaxDist;
   off->set(0,0,0);
   rot->identity();
}


//----------------------------------------------------------------------------
F32 ShapeBase::getDamageFlash() const
{
   return mDamageFlash;
}

void ShapeBase::setDamageFlash(const F32 flash)
{
   mDamageFlash = flash;
   if (mDamageFlash < 0.0)
      mDamageFlash = 0;
   else if (mDamageFlash > 1.0)
      mDamageFlash = 1.0;
}


//----------------------------------------------------------------------------
F32 ShapeBase::getWhiteOut() const
{
   return mWhiteOut;
}

void ShapeBase::setWhiteOut(const F32 flash)
{
   mWhiteOut = flash;
   if (mWhiteOut < 0.0)
      mWhiteOut = 0;
   else if (mWhiteOut > 1.5)
      mWhiteOut = 1.5;
}


//----------------------------------------------------------------------------

bool ShapeBase::onlyFirstPerson() const
{
   return mDataBlock->firstPersonOnly;
}

bool ShapeBase::useObjsEyePoint() const
{
   return mDataBlock->useEyePoint;
}


//----------------------------------------------------------------------------
F32 ShapeBase::getInvincibleEffect() const
{
   return mInvincibleEffect;
}

void ShapeBase::setupInvincibleEffect(F32 time, F32 speed)
{
   if(isClientObject())
   {
      mInvincibleCount = mInvincibleTime = time;
      mInvincibleSpeed = mInvincibleDelta = speed;
      mInvincibleEffect = 0.0f;
      mInvincibleOn = true;
      mInvincibleFade = 1.0f;
#ifndef TGE_RPGCLIENT2 /// TGE_RPGIsClientObject
   }
   else
   {
      mInvincibleTime  = time;
      mInvincibleSpeed

⌨️ 快捷键说明

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