fix: test move with brush.

This commit is contained in:
Tungdv
2026-02-10 11:12:12 +07:00
parent 0702571c04
commit 077a76f77e
6 changed files with 349 additions and 18 deletions
@@ -297,7 +297,7 @@ namespace BrewMonster.Scripts
FinishWorkAtPriority(iPriority);
WorkList workList = m_WorkStack[iPriority];
workList.Add(pWork);
BMLogger.LogError("m_WorkStack " + pWork.GetWorkID());
//BMLogger.LogError("m_WorkStack " + pWork.GetWorkID());
if (shouldStart)
{
if (iPriority > m_iCurPriority)
@@ -712,9 +712,9 @@ namespace BrewMonster.Scripts
{
m_pHost.SetRotationHP(vMoveDir);
}
Debug.LogError("m_pHost pos = " + m_pHost.transform.position + " m_pHost.m_aabbServer.Center = " + EC_Utility.ToVector3(m_pHost.m_aabbServer.Center));
vCurPos = m_pHost.m_MoveCtrl.GroundMove(EC_Utility.ToA3DVECTOR3(vMoveDir), fSpeed, fDeltaTime, m_pHost.m_fVertSpeed);
//Debug.LogError("vCurPos =" + vCurPos);
Debug.LogError("spped =" + Vector3.Distance(EC_Utility.ToVector3(vCurPos), m_pHost.transform.position) / fDeltaTime);
m_pHost.SetPos(EC_Utility.ToVector3(vCurPos));
}
else
@@ -29,9 +29,12 @@ namespace BrewMonster.Scripts
public uint dwUser1; // User defined data 1
public uint dwUser2; // User defined data 2
// For test
public A3DVECTOR3 normal;
public void Init(A3DVECTOR3 start, A3DVECTOR3 delta, A3DVECTOR3 ext, bool bRay = false, float epsilon = 0.03125f)
{
BoundAABB = new A3DAABB();
vStart = start;
vDelta = delta;
vExtents = ext;
@@ -82,6 +82,7 @@ namespace BrewMonster
);
// Record this position
Debug.LogError("Record this position");
m_vLastSevPos = EC_Utility.ToA3DVECTOR3(m.vPos);
Reset();
@@ -307,6 +308,7 @@ namespace BrewMonster
//CECInstance pInstance = g_pGame.GetGameRun().GetInstance(idInst);
//if (pInstance.GetLimitJump())
//fGravity *= 4.0f;
Vector3 posStart = EC_Utility.ToVector3(m_pHost.m_aabbServer.Center);
CDR_INFO cdr = m_pHost.m_CDRInfo;
cdr.vCenter = m_pHost.m_aabbServer.Center;
cdr.vXOZVelDir = vRealDirH;
@@ -314,7 +316,7 @@ namespace BrewMonster
cdr.t = fTime;
cdr.fGravityAccel = fGravity;
cdr.fYVel += fSpeedV;
EC_CDR.OnGroundMove(ref cdr);
EC_CDR.OnGroundMove_test(ref cdr);
m_pHost.m_CDRInfo = cdr;
//if (g_pGame.GetGameRun().GetWorld().GetAssureMove())
// g_pGame.GetGameRun().GetWorld().GetAssureMove().AssureMove(m_pHost.m_aabbServer.Center, cdr.vCenter);
@@ -345,6 +347,7 @@ namespace BrewMonster
m_fMoveTime += fTime;
m_pHost.m_CDRInfo.vTPNormal = cdr.vTPNormal;
//Debug.LogError("speed = " + (Vector3.Distance(posStart, EC_Utility.ToVector3(vNewPos)) / fTime));
return vNewPos;
}
+332 -7
View File
@@ -123,7 +123,6 @@ namespace BrewMonster
if ((pEnvTrc.dwCheckFlag & CDR_EVN.CDR_BRUSH) == CDR_EVN.CDR_BRUSH)
{
dir = vDelta;
float num = 10f;
Vector3[] arrVExt = new Vector3[5] {
vExt
@@ -132,12 +131,13 @@ namespace BrewMonster
new Vector3(vExt.x, vExt.y, vExt.z / num),
vExt / num
};
for(int i = 0; i < arrVExt.Length; i++)
dir = vStart + vDelta;
for (int i = 0; i < arrVExt.Length; i++)
{
countHits = Physics.BoxCastNonAlloc(vStart, vExt, dir.normalized, hits, Quaternion.identity, vDelta.magnitude, BrushMask);
countHits = Physics.BoxCastNonAlloc(vStart, arrVExt[i], dir.normalized, hits, Quaternion.identity, vDelta.magnitude, BrushMask);
if (countHits > 0 && hits[0].distance > 0.0009f)
{
pEnvTrc.fFraction = (hits[0].distance - vExt.x) / vDelta.magnitude;
pEnvTrc.fFraction = (hits[0].distance) / vDelta.magnitude;
pEnvTrc.vHitNormal = EC_Utility.ToA3DVECTOR3(hits[0].normal);
pEnvTrc.dwClsFlag = CDR_EVN.CDR_BRUSH;
break;
@@ -301,7 +301,7 @@ namespace BrewMonster
bool bTryPull = false;
int nTry = 0;
LayerMask mask = UsedMask_Ground();
LayerMask mask = UsedMask_Ground() | BrushMask;
env_trace_t trcInfo = new env_trace_t();
trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH;
@@ -460,6 +460,328 @@ namespace BrewMonster
CDRInfo.vTPNormal = EC_Utility.ToA3DVECTOR3(vTPNormal);
}
public static void OnGroundMove_test(ref CDR_INFO CDRInfo)
{
float VEL_EPSILON = 1E-4f;
float DIST_EPSILON = 1e-4f;
float NORMAL_EPSILON = 1e-2f;
float MAX_TRY = 4;
float VEL_MAX_SPEED = 200.0f;
float VEL_REFLECT = 0.3f;
CDRInfo.fMoveDist = 0.0f; //clear the moving dist
bool bFreeFall = (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh);
if (CDRInfo.fYVel < VEL_EPSILON && CDRInfo.fYVel > -VEL_EPSILON && CDRInfo.fSpeed < VEL_EPSILON && CDRInfo.fSpeed > -VEL_EPSILON && !bFreeFall)
{
return;
}
float fYVel = CDRInfo.fYVel; //save the y velocity;
//@todo : refine the speed to determine the jumping state. By Kuiwu[14/9/2005]
bool bJump = (fYVel > 0.5f);
//bool bJump = (fYVel > CDRInfo.fGravityAccel * 0.1f);
A3DVECTOR3 vVelocity = new A3DVECTOR3(CDRInfo.fSpeed* CDRInfo.vXOZVelDir +fYVel * GPDataTypeHelper.g_vAxisY );
if (bFreeFall)
{
vVelocity -= (CDRInfo.fGravityAccel * CDRInfo.t * GPDataTypeHelper.g_vAxisY);
fYVel -= CDRInfo.fGravityAccel * CDRInfo.t;
}
A3DVECTOR3 vVelDir = (vVelocity);
float fVelSpeed = vVelDir.Normalize();
if (!bFreeFall)
{
AAssist.a_ClampRoof(ref fVelSpeed, VEL_MAX_SPEED);
}
vVelocity = vVelDir * fVelSpeed;
//@note : clip the velocity or dir? By Kuiwu[8/9/2005]
float dtp = DotProduct(vVelDir, CDRInfo.vTPNormal);
if (dtp < 0.0f || !bJump)
{
vVelocity = (vVelDir - CDRInfo.vTPNormal * dtp - CDRInfo.vTPNormal * dtp * 0.01f) * fVelSpeed;
//a_LogOutput(1, "dtp < 0.0f || !bJump vVelocity = (%f, %f, %f) || CDRInfo.vTPNormal = (%f, %f, %f)", vVelocity.x, vVelocity.y, vVelocity.z, CDRInfo.vTPNormal.x, CDRInfo.vTPNormal.y, CDRInfo.vTPNormal.z);
}
CDRInfo.vAbsVelocity = vVelocity;
A3DVECTOR3 vStart = (CDRInfo.vCenter);
A3DVECTOR3 vExt = (CDRInfo.vExtent);
float fTime = CDRInfo.t;
//A3DVECTOR3 vDelta(vVelocity * fTime);
A3DVECTOR3 vDelta;
bool bClear = true;
int nTry = 0;
env_trace_t trcInfo = new env_trace_t();
trcInfo.dwCheckFlag = CDR_EVN.CDR_TERRAIN | CDR_EVN.CDR_BRUSH;
trcInfo.vExt = vExt;
//A3DVECTOR3 vNormal, vFinalPos(vStart);
A3DVECTOR3 vNormal, vFinalPos = new A3DVECTOR3();
bool bPull = false;
bool bTryPull = false;
while (nTry < MAX_TRY)
{
vDelta = vVelocity * fTime;
vFinalPos = vStart;
float fDeltaDist = vDelta.Magnitude();
//a_LogOutput(1, "fDeltaDist = %f || vVelocity = (%f, %f, %f) || fTime = %f", fDeltaDist, vVelocity.x, vVelocity.y, vVelocity.z, fTime);
//if (vDelta.SquaredMagnitude() < DIST_EPSILON )
if (fDeltaDist < DIST_EPSILON)
{
Debug.LogError("EC_CDR fDeltaDist < DIST_EPSILON");
break;
}
trcInfo.vStart = vStart;
trcInfo.vDelta = vDelta;
trcInfo.vTerStart = vStart;
trcInfo.vTerStart.y -= vExt.y; //foot
bClear = !CollideWithEnv(ref trcInfo);
++nTry;
if (trcInfo.bStartSolid)
{
//Debug.LogError("EC_CDR trcInfo.bStartSolid = true");
CDRInfo.fMoveDist = 0.0f;
if (CDRInfo.vTPNormal.y < CDRInfo.fSlopeThresh)
{
CDRInfo.vTPNormal = new A3DVECTOR3(0.0f, 1.0f, 0.0f);
}
//a_LogOutput(1, "bClear = true but trcInfo.bStartSolid = true");
return;
}
if (bClear)
{
//a_LogOutput(1, "bClear = true");
vFinalPos = vStart + vDelta;
// Debug.LogError("EC_CDR bClear = true vFinalPos = " + vFinalPos + " fTime = " + fTime + "vVelocity = " + vVelocity + " speed = " + vVelocity.Magnitude());
break;
}
//Debug.LogError("EC_CDR trcInfo.fFraction = " + trcInfo.fFraction);
vStart += vDelta * trcInfo.fFraction;
fTime -= fTime * trcInfo.fFraction;
vNormal = trcInfo.vHitNormal;
if (!bFreeFall && !bTryPull && !bJump)
{
env_trace_t tmpInfo = new env_trace_t();
tmpInfo.vStart = vStart;
tmpInfo.vDelta = new A3DVECTOR3(0.0f, CDRInfo.fStepHeight, 0.0f);
tmpInfo.vExt = vExt;
//@note : need check terrain?? By Kuiwu[8/10/2005]
tmpInfo.dwCheckFlag = CDR_EVN.CDR_BRUSH | CDR_EVN.CDR_TERRAIN;
tmpInfo.vTerStart = vStart;
tmpInfo.vTerStart.y -= vExt.y;
bPull = !CollideWithEnv(ref tmpInfo);
if (bPull)
{
vStart.y += CDRInfo.fStepHeight;
//vDelta = vVelocity * fTime;
vDelta = vVelocity;
tmpInfo.vStart = vStart;
tmpInfo.vDelta = vDelta;
tmpInfo.vTerStart = vStart;
tmpInfo.vTerStart.y -= vExt.y;
bool bMove = !CollideWithEnv(ref tmpInfo);
if (!bMove)
{
vDelta *= tmpInfo.fFraction;
}
if (vDelta.SquaredMagnitude() < vExt.x * vExt.x * 4)
{
vStart.y -= CDRInfo.fStepHeight;
bPull = false;
}
}
bTryPull = true;
}
if (!bPull)
{
fVelSpeed = Normalize(vVelocity, ref vVelDir);
fVelSpeed *= (1 - nTry * 0.1f);
dtp = DotProduct(vNormal, vVelDir);
float fRelSpeed = EC_Utility.a_Min(fVelSpeed, 5.0f);
if ((dtp < 1E-4f) && (dtp >= 0.0f))
{//@note : special parallel tangent plane case, rarely happen. By Kuiwu[20/10/2005]
vVelocity += vNormal * VEL_REFLECT * fRelSpeed;
}
else
{
vVelocity = (vVelDir - vNormal * dtp) * fVelSpeed - vNormal * dtp * VEL_REFLECT * fRelSpeed;
//vVelocity = (vVelDir - vNormal * dtp - vNormal*dtp * VEL_REFLECT) * fVelSpeed;
}
//CDRInfo.fYVel = vVelocity.y;
if (fYVel > VEL_EPSILON)
{
if ((vNormal.y >= CDRInfo.fSlopeThresh || vNormal.y < -NORMAL_EPSILON))
{
fYVel = 0.0f;
}
}
else if (fYVel < -VEL_EPSILON)
{
if ((vNormal.y >= CDRInfo.fSlopeThresh))
{
fYVel = 0.0f;
}
}
else
{
//@note : additional handle something??? By Kuiwu[13/9/2005]
}
}
}
////@note : prevent moving to the invalid area. By Kuiwu[20/9/2005]
//if (!IsPosInAvailableMap(vFinalPos))
//{
// CDRInfo.fMoveDist = 0.0f;
// return;
//}
A3DVECTOR3 vTPNormal = new A3DVECTOR3();
vTPNormal.Clear();
ground_trace_t groundTrc = new ground_trace_t();
groundTrc.vStart = vFinalPos;
groundTrc.vExt = vExt;
groundTrc.fDeltaY = 0.3f;
if (bPull)
{
groundTrc.fDeltaY = CDRInfo.fStepHeight + 0.1f;
}
if (bJump)
{
groundTrc.fDeltaY = 0.0f;
}
if (!RetrieveSupportPlane(ref groundTrc))
{//@note : do NOT change position. By Kuiwu[14/9/2005]
CDRInfo.fMoveDist = 0.0f;
// if (groundTrc.bSupport)
// {
// CDRInfo.vTPNormal = groundTrc.vHitNormal;
// }
CDRInfo.vTPNormal = new A3DVECTOR3(0.0f, 1.0f, 0.0f);
Debug.LogError("EC_CDR RetrieveSupportPlane = false");
return;
}
if (groundTrc.bSupport)
{
Debug.LogError("EC_CDR groundTrc.bSupport = true groundTrc.vStart = " + groundTrc.vStart + " groundTrc.vEnd = " + groundTrc.vEnd);
Debug.DrawLine(EC_Utility.ToVector3(groundTrc.vStart), EC_Utility.ToVector3(groundTrc.vEnd), Color.green, 10f);
vFinalPos = groundTrc.vEnd;
if (!bJump)
{
vTPNormal = groundTrc.vHitNormal;
}
}
if ((vTPNormal.y >= CDRInfo.fSlopeThresh && fYVel < 0.0f)
|| (!bJump && fYVel > 0.0f))
{
fYVel = 0.0f;
}
CDRInfo.vCenter = vFinalPos;
CDRInfo.fYVel = fYVel; //set back the y velocity
CDRInfo.vTPNormal = vTPNormal;
}
//@desc : used to retrieve support plane (ground or brush), By Kuiwu[12/9/2005]
public struct ground_trace_t
{
public A3DVECTOR3 vStart;
public A3DVECTOR3 vExt;
public float fDeltaY; //down (-y)
public A3DVECTOR3 vEnd;
public A3DVECTOR3 vHitNormal;
public bool bSupport; //false if ground missed
};
public static bool RetrieveSupportPlane(ref ground_trace_t pTrc)
{
A3DVECTOR3 vTerrainPos = new A3DVECTOR3(), vTerrainNormal = new A3DVECTOR3();
GetTerrainInfo(pTrc.vStart, ref vTerrainPos, ref vTerrainNormal);
pTrc.bSupport = false;
// pTrc.vEnd = pTrc.vStart;
// pTrc.vEnd.y -= pTrc.fDeltaY;
BrushTraceInfo trcInfo = new BrushTraceInfo();
trcInfo.Init(pTrc.vStart, new A3DVECTOR3(0.0f, -pTrc.fDeltaY, 0.0f), pTrc.vExt);
if (AABBCollideWithBrush(ref trcInfo))
{
// if (trcInfo.bStartSolid && (!RescueFromSolid(&trcInfo)))
// {
// pTrc.bSupport = true;
// pTrc.vHitNormal = vTerrainNormal;
// pTrc.vEnd = pTrc.vStart;
// return false;
// }
if (trcInfo.bStartSolid)
{
return false;
}
pTrc.vEnd = trcInfo.vStart + trcInfo.vDelta * trcInfo.fFraction;
pTrc.vHitNormal = trcInfo.normal;
float fUp = pTrc.vExt.y;
if (pTrc.vEnd.y > vTerrainPos.y + fUp)
{
pTrc.vStart = trcInfo.vStart;
pTrc.bSupport = true;
return true;
}
}
//if (vTerrainPos.y > pTrc.vStart.y- pTrc.vExt.y )
if (vTerrainPos.y > pTrc.vStart.y - pTrc.vExt.y || (vTerrainPos.y <= pTrc.vStart.y - pTrc.vExt.y && vTerrainPos.y >= pTrc.vStart.y - pTrc.vExt.y - pTrc.fDeltaY))
{
pTrc.vEnd = vTerrainPos;
//@note : maybe sink in the sleep ground, but this is what I need. By Kuiwu[14/9/2005]
pTrc.vEnd.y += (pTrc.vExt.y + 0.01f);
A3DVECTOR3 vDelta = new A3DVECTOR3(pTrc.vEnd -pTrc.vStart);
trcInfo.Init(pTrc.vStart, vDelta, pTrc.vExt);
pTrc.vHitNormal = vTerrainNormal;
pTrc.bSupport = true;
return !AABBCollideWithBrush(ref trcInfo);
}
return true;
}
public static void GetTerrainInfo(A3DVECTOR3 vPos, ref A3DVECTOR3 vPosOnSurface, ref A3DVECTOR3 vNormal)
{
vPosOnSurface = vPos;
int countHits = 0;
countHits = Physics.RaycastNonAlloc(EC_Utility.ToVector3(vPosOnSurface), Vector3.down, fHitsTerrain, 1000f, TerrainMask | BrushMask);
if (countHits > 0)
{
vPosOnSurface.y = fHitsTerrain[0].point.y;
vNormal = EC_Utility.ToA3DVECTOR3(fHitsTerrain[0].normal);
}
}
// Get normalize
static float Normalize(A3DVECTOR3 vIn, ref A3DVECTOR3 vOut)
{
@@ -659,6 +981,7 @@ namespace BrewMonster
Vector3 dir = vDelta;
int countHits = 0;
float num = 10f;
Quaternion quaternion = EC_Game.GetGameRun().GetWorld().GetPlayerMan().GetHostPlayer().transform.rotation;
Vector3[] arrVExt = new Vector3[5] {
vExt
,new Vector3(vExt.x / num, vExt.y, vExt.z),
@@ -668,16 +991,18 @@ namespace BrewMonster
};
for (int i = 0; i < arrVExt.Length; i++)
{
countHits = Physics.BoxCastNonAlloc(vStart, vExt, dir.normalized, hits, Quaternion.identity, vDelta.magnitude, BrushMask);
countHits = Physics.BoxCastNonAlloc(vStart, arrVExt[i], dir.normalized, hits, Quaternion.identity, vDelta.magnitude, BrushMask);
if (countHits > 0)
{
if(hits[0].distance > 0.0009f)
{
brushTraceInfo.fFraction = (hits[0].distance - vExt.x) / vDelta.magnitude;
brushTraceInfo.fFraction = (hits[0].distance) / vDelta.magnitude;
brushTraceInfo.normal = EC_Utility.ToA3DVECTOR3(hits[0].normal);
return true;
}
}
}
brushTraceInfo.normal = new A3DVECTOR3(0f);
brushTraceInfo.fFraction = 100f;
return false;
}
+6 -6
View File
@@ -430,13 +430,13 @@ namespace BrewMonster
// ccRadius = controller.radius; ccSkin = controller.skinWidth;
EstimateMoveEnv(GetPos());
OnKeyDown();
m_pWorkMan?.Tick(Time.deltaTime);
// track status of Task
TickTask();
// Update timers
UpdateTimers(Time.deltaTime);
m_pWorkMan?.Tick(Time.deltaTime);
// Update GFXs
@@ -2762,7 +2762,7 @@ namespace BrewMonster
handle.AddrOfPinnedObject(), typeof(cmd_host_correct_pos));
handle.Free();
//cmd_host_correct_pos pCmd = GPDataTypeHelper.FromBytes<cmd_host_correct_pos>((byte[])Msg.dwParam1);
//Debug.LogError("HoangDev :pCmd.pos " + pCmd.pos);
Debug.LogError("HoangDev :pCmd.pos " + pCmd.pos);
SetPos(pCmd.pos);
m_vVelocity.Clear();
m_CDRInfo.vAbsVelocity.Clear();
@@ -6233,13 +6233,13 @@ namespace BrewMonster
LayerMask layerMaskTerrain = 1 << 6;
LayerMask layerMaskBush = 1 << 7;
if (Physics.RaycastNonAlloc(vPos, (Vector3.down), hits, 1000f, layerMaskTerrain) > 0)
if (Physics.RaycastNonAlloc(vPos, (Vector3.down), hits, 1000f, layerMaskTerrain) > 0 && hits[0].distance > 0.0009f)
{
vTerrainPos = hits[0].point;
vTerrainNormal = hits[0].normal;
}
if (Physics.RaycastNonAlloc(vPos, (Vector3.down), hits, DeltaY, layerMaskBush) > 0)
if (Physics.RaycastNonAlloc(vPos, (Vector3.down), hits, DeltaY, layerMaskBush) > 0 && hits[0].distance > 0.0009f)
{
if (vBuildingPos.y > vTerrainPos.y)
{
@@ -6270,7 +6270,7 @@ namespace BrewMonster
hits = new RaycastHit[5];
int count = Physics.BoxCastNonAlloc(vCenter, vExt, (Vector3.down).normalized,
hits, transform.rotation, DeltaY, layerMask);
if (count == 0)
if (count == 0 && hits[0].distance > 0.0009f)
{
vHitPos = vCenter;
vHitNormal = EC_Utility.ToA3DVECTOR3(Vector3.up);
@@ -6282,7 +6282,7 @@ namespace BrewMonster
// halfBox with y = 0.05f? I need Y box check too small.
count = Physics.BoxCastNonAlloc(vCenter, new Vector3(vExt.x, 0.05f, vExt.z), (Vector3.down).normalized,
hits, transform.rotation, DeltaY, layerMask);
if (count == 0)
if (count == 0 && hits[0].distance > 0.0009f)
{
vHitPos = vCenter;
vHitNormal = EC_Utility.ToA3DVECTOR3(Vector3.up);