📄 shapebase.cc
字号:
#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 + -