コード例 #1
0
bool ZCharacterObject::GetHistory(rvector *pos, rvector *direction, float fTime)
{
    if(GetVisualMesh() == NULL)
        return false;

    if(m_BasicHistory.size()>1)
    {
        ZBasicInfoHistory::iterator hi;
        hi=m_BasicHistory.end();

        // ½Ã°£¼øÀ¸·Î bi < fTime < binext µÇµµ·Ï µÎ°³ÀÇ µÎ ¾ÆÀÌÅÛÀ» ¼±ÅÃ

        ZBasicInfoItem *bi=NULL,*binext=NULL;

        do {
            hi--;
            binext=bi;
            bi=*hi;

        } while(hi!=m_BasicHistory.begin() && bi->fSendTime>fTime);

        if(fTime<bi->fSendTime) // ¿ª»ç°¡ ±â·ÏµÈ ÀÌÀüÀÇ µ¥ÀÌÅ͸¦ ¿ä±¸Çϸé Á¿Ä¡¾Ê´Ù
            return false;

        ZBasicInfoItem *pnext,next;

        if(!binext)
        {
            if(fTime>=ZGetGame()->GetTime())	// ¹Ì·¡ÀÇ À§Ä¡´Â ¾Ë¼ö¾ø´Ù. ÇöÀçÀÇ À§Ä¡¸¦ ¸®ÅÏÇÑ´Ù
            {
                *pos=GetPosition();
                *direction = m_Direction;
//				*headpos=GetVisualMesh()->GetHeadPosition();
//				if(direction_low) *direction_low = m_DirectionLower;
                return true;
            }

            next.fSendTime=ZGetGame()->GetTime();
            next.info.position=GetPosition();
            next.info.direction=m_Direction;
//			next.info.lowerstate=m_AniState_Lower;
            pnext=&next;
        } else
            pnext=binext;

        float t=(fTime-bi->fSendTime)/(pnext->fSendTime-bi->fSendTime);

        *pos = bi->info.position *(1-t) + pnext->info.position*t;
//		*headpos = bi->info.headpos*(1-t) + pnext->headpos*t;
//		*headpos=GetVisualMesh()->GetHeadPosition();
        *direction = InterpolatedVector(bi->info.direction,pnext->info.direction,t);
//		if(direction_low) *direction_low = InterpolatedVector(bi->info.direction_low,pnext->direction_low,t);

        return true;
    } else
    {
        // ¾Æ¸¶µµ ÀÎÇü ?
        *pos=GetPosition();
        *direction=m_Direction;
//		if(direction_low) *direction_low=m_DirectionLower;
//		*headpos=GetVisualMesh()->GetHeadPosition();
        return true;
    }

    return false;
}
コード例 #2
0
v3 GetNormal(const RCONVEXPOLYGONINFO *poly, const rvector &position,
	int au, int av)
{
	int nSelPolygon = -1, nSelEdge = -1;
	float fMinDist = FLT_MAX;

	if (poly->nVertices == 3)
		nSelPolygon = 0;
	else
	{
		rvector pnormal(poly->plane.a, poly->plane.b, poly->plane.c);

		for (int i = 0; i < poly->nVertices - 2; i++)
		{
			const auto& a = poly->pVertices[0];
			const auto& b = poly->pVertices[i + 1];
			const auto& c = poly->pVertices[i + 2];

			if (IntersectTriangle(a, b, c, position + pnormal, -pnormal, nullptr))
			{
				nSelPolygon = i;
				nSelEdge = -1;
				break;
			}
			else
			{
				float dist = GetDistance(position, a, b);
				if (dist < fMinDist) { fMinDist = dist; nSelPolygon = i; nSelEdge = 0; }
				dist = GetDistance(position, b, c);
				if (dist < fMinDist) { fMinDist = dist; nSelPolygon = i; nSelEdge = 1; }
				dist = GetDistance(position, c, a);
				if (dist < fMinDist) { fMinDist = dist; nSelPolygon = i; nSelEdge = 2; }
			}
		}
	}

	auto& v0 = poly->pVertices[0];
	auto& v1 = poly->pVertices[nSelPolygon + 1];
	auto& v2 = poly->pVertices[nSelPolygon + 2];

	auto& n0 = poly->pNormals[0];
	auto& n1 = poly->pNormals[nSelPolygon + 1];
	auto& n2 = poly->pNormals[nSelPolygon + 2];

	v3 pos;
	if (nSelEdge != -1)
	{
		auto& e0 = nSelEdge == 0 ? v0 : nSelEdge == 1 ? v1 : v2;
		auto& e1 = nSelEdge == 0 ? v1 : nSelEdge == 1 ? v2 : v0;

		auto dir = Normalized(e1 - e0);

		pos = e0 + DotProduct(dir, position - e0) * dir;
	}
	else
		pos = position;

	auto a = v1 - v0;
	auto b = v2 - v1;
	auto x = pos - v0;

	float f = b[au] * x[av] - b[av] * x[au];
	if (IS_ZERO(f))
		return n0;

	float t = (a[av] * x[au] - a[au] * x[av]) / f;

	auto tem = InterpolatedVector(n1, n2, t);

	auto inter = a + t*b;

	int axisfors;
	if (fabs(inter.x) > fabs(inter.y) && fabs(inter.x) > fabs(inter.z))
		axisfors = 0;
	else if (fabs(inter.y) > fabs(inter.z))
		axisfors = 1;
	else
		axisfors = 2;

	float s = x[axisfors] / inter[axisfors];
	return InterpolatedVector(n0, tem, s);
}
コード例 #3
0
bool MPathTracer::ProcMove(rvector* pNewPos, rvector* pNewDir, rvector* pNewVelocity, rvector* pDir, rvector& Distance, rvector& RealDistance, bool bSmoothArrival)
{
    //if(Velocity.x==0.0f && Velocity.y==0.0f && Velocity.z==0.0f) return true;	// 같은 위치면 도착

    float fDistance = Distance.GetMagnitude();

    rvector TargetDir2D(m_Dir);
    if(Distance.x!=0.0f || Distance.y!=0.0f || Distance.z!=0.0f) {
        TargetDir2D = Distance;
        TargetDir2D.z = 0;
        TargetDir2D.Normalize();
    }
    if(pDir!=NULL) {
        _ASSERT(pDir->z==0.0f);
        // 방향 설정은 보정된 Distance가 아닌 RealDistance에 의존한다.
        float fRealDistance = RealDistance.GetMagnitude();
        if(fRealDistance<=m_Property.fMaxVelocity*m_fDirectionSettingConstant) {
            float fDirectionWeightConstant = max(min((1-fRealDistance/(m_Property.fMaxVelocity*m_fDirectionSettingConstant)), 1), 0);
            TargetDir2D = Normalize(InterpolatedVector(TargetDir2D, Normalize(*pDir), fDirectionWeightConstant));
        }
    }

    // 회전
    ////////////////////////////////////////////////////////////
    float fDiffAngle = GetAngleOfVectors(TargetDir2D, m_Dir);
    float fRotateAngle = fDiffAngle;

    float fRotatePercent = 1.0f;

    // 회전 가/감속
    if(fDiffAngle>0) {
        m_fAngularVelocity = min(m_Property.fMaxRotationVelocity, m_fAngularVelocity + m_Property.fRotationAcceleration);
        if(fabs(fDiffAngle)<m_Property.fMaxRotationVelocity*m_nAgularDecelerationConstant) {
            m_fAngularVelocity = min(m_fAngularVelocity, fDiffAngle/m_nAgularDecelerationConstant);
        }
    }
    else if(fDiffAngle<0) {
        m_fAngularVelocity = max(-m_Property.fMaxRotationVelocity, m_fAngularVelocity - m_Property.fRotationAcceleration);
        if(fabs(fDiffAngle)<m_Property.fMaxRotationVelocity*m_nAgularDecelerationConstant) {
            m_fAngularVelocity = max(m_fAngularVelocity, fDiffAngle/m_nAgularDecelerationConstant);
        }
    }

    if(fDiffAngle!=0.0f) fRotatePercent = m_fAngularVelocity/fDiffAngle;

    rvector NewDir = Normalize(InterpolatedVector(m_Dir, Normalize(TargetDir2D), fRotatePercent));

    // 결과 값
    //m_fResultRotatePercent = fRotateAngle / m_Property.fMaxRotationVelocity;
    m_fResultRotatePercent = GetAngleOfVectors(NewDir, m_Dir) / m_Property.fMaxRotationVelocity;	// 버그로 인해 실제 계산값을 입력

    bool bArriveAngle = false;
    if(fRotatePercent==1.0f) bArriveAngle = true;

    // 가속 & 이동
    ////////////////////////////////////////////////////////////

    // 현재 가능 가속도 계산
    rvector Acceleration = Clip(Distance-m_Velocity, m_Property.fAcceleration);
    //rvector Acceleration = NewDir*m_Property.fAcceleration;
    float fAcceleration = Acceleration.GetMagnitude();
    if(fAcceleration>=0.0f) {
        if(m_bDirectionSpeed==true) {	// 방향에 따른 가감속
            fAcceleration -= (fAcceleration*max(min((float)fabs(fDiffAngle)/pi, 1), 0)*m_nDirectionalSpeedContant);
            Acceleration = Normalize(Acceleration)*fAcceleration;
        }
    }

    // 현재 가능 속도 계산
    rvector NewVelocity = m_Velocity + Acceleration;
    //float fNewVelocity = NewVelocity.GetMagnitude();
    Clip(&NewVelocity, m_Property.fMaxVelocity);	// Clip

    bool bArrive = false;
    // 거리에 따른 속도 조절
    float fNewVelocity = NewVelocity.GetMagnitude();
    if(bSmoothArrival==true && fDistance<=m_Property.fMaxVelocity*m_nDecelerationConstant) {
        float t = fDistance/(m_Property.fMaxVelocity*m_nDecelerationConstant);
        //_ASSERT(m_nDecelerationCurveConstant>=1.0f);
        fNewVelocity = min(fNewVelocity, m_Property.fMaxVelocity*(float)pow((t), m_nDecelerationCurveConstant));
        NewVelocity = Normalize(NewVelocity)*fNewVelocity;
        if(fNewVelocity<=m_Property.fMaxVelocity*m_fArrivalConstant) bArrive = true;
    }
    else if(fNewVelocity>=fDistance) bArrive = true;

    // New Values
    *pNewVelocity = NewVelocity;
    *pNewDir = NewDir;
    *pNewPos = m_Pos+NewVelocity;

    return bArrive;
}