fix: update logic check bush.
This commit is contained in:
+210
-73
@@ -1,4 +1,6 @@
|
||||
using BrewMonster.Scripts.World;
|
||||
using BrewMonster.Scripts.Ornament;
|
||||
using BrewMonster.Scripts.Player;
|
||||
using BrewMonster.Scripts.World;
|
||||
using CSNetwork.GPDataType;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
@@ -12,6 +14,7 @@ namespace BrewMonster.Scripts
|
||||
public static LayerMask BrushMask { get; set; } = ~0;
|
||||
public static LayerMask TerrainMask { get; set; } = ~0;
|
||||
|
||||
const float LOCAL_EPSILON = 1e-5f;
|
||||
//[Flags]
|
||||
public class CDR_EVN
|
||||
{
|
||||
@@ -63,20 +66,20 @@ namespace BrewMonster.Scripts
|
||||
A3DVECTOR3 vWatNormal = new A3DVECTOR3();
|
||||
bool bStart = false;
|
||||
//@todo : TBD: use center or foot? By Kuiwu[10/10/2005]
|
||||
if (CollideWithWater(pEnvTrc.vWatStart, pEnvTrc.vDelta, pEnvTrc.bWaterSolid, ref fFraction, ref vWatNormal, ref bStart)
|
||||
&& fFraction < pEnvTrc.fFraction)
|
||||
{
|
||||
pEnvTrc.fFraction = fFraction;
|
||||
pEnvTrc.vHitNormal = vWatNormal;
|
||||
pEnvTrc.bStartSolid = bStart;
|
||||
pEnvTrc.dwClsFlag = CDR_EVN.CDR_WATER;
|
||||
//# ifdef CDR_DEBUG
|
||||
// A3DVECTOR3 vHitPos(pEnvTrc.vWatStart +pEnvTrc.vDelta * fFraction);
|
||||
// sprintf(msg, "collide water, fraction %f pos %f %f %f \n", fFraction, vHitPos.x, vHitPos.y, vHitPos.z);
|
||||
// OUTPUT_DEBUG_INFO(msg);
|
||||
//#endif
|
||||
//if (CollideWithWater(pEnvTrc.vWatStart, pEnvTrc.vDelta, pEnvTrc.bWaterSolid, ref fFraction, ref vWatNormal, ref bStart)
|
||||
// && fFraction < pEnvTrc.fFraction)
|
||||
//{
|
||||
// pEnvTrc.fFraction = fFraction;
|
||||
// pEnvTrc.vHitNormal = vWatNormal;
|
||||
// pEnvTrc.bStartSolid = bStart;
|
||||
// pEnvTrc.dwClsFlag = CDR_EVN.CDR_WATER;
|
||||
// //# ifdef CDR_DEBUG
|
||||
// // A3DVECTOR3 vHitPos(pEnvTrc.vWatStart +pEnvTrc.vDelta * fFraction);
|
||||
// // sprintf(msg, "collide water, fraction %f pos %f %f %f \n", fFraction, vHitPos.x, vHitPos.y, vHitPos.z);
|
||||
// // OUTPUT_DEBUG_INFO(msg);
|
||||
// //#endif
|
||||
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
return (pEnvTrc.fFraction < 1.0f + 1E-4f);
|
||||
@@ -311,83 +314,217 @@ namespace BrewMonster.Scripts
|
||||
if (vTPNormal != Vector3.zero) CDRInfo.vTPNormal = vTPNormal;
|
||||
}
|
||||
|
||||
bool CollideWithTerrain(A3DVECTOR3 vStart, A3DVECTOR3 vDelta, ref float fFraction, ref A3DVECTOR3 vHitNormal, ref bool bStart)
|
||||
{
|
||||
static bool SegmentTriangleIntersect(A3DVECTOR3 vStart, A3DVECTOR3 vDelta, A3DVECTOR3[] vert, ref float fFraction, bool bCull)
|
||||
{
|
||||
float dist = 0f;
|
||||
A3DVECTOR3 vDir = new A3DVECTOR3(vDelta);
|
||||
|
||||
dist = vDir.Normalize();
|
||||
if (dist < 1E-5f)
|
||||
{
|
||||
//assert(0 && "too small dist!");
|
||||
fFraction = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
float t = 0f, u = 0f, v = 0f;
|
||||
|
||||
if (RayTriangleIntersect(vStart, vDir, vert, ref t, ref u, ref v, bCull) && (t >= 0.0f) && (t <= dist))
|
||||
{
|
||||
//fFraction = t/dist;
|
||||
//fFraction = a_Max( 0.0f, fFraction -1E-4f); //put back
|
||||
fFraction = (t - 5E-4f) / dist;
|
||||
AAssist.a_ClampFloor(ref fFraction, 0.0f);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* ray: origin + t* dir, triangle: p(u,v) = (1-u -v)vert[0] + u*vert[1] + v*vert[2]
|
||||
* @desc :
|
||||
* @param vDir: normalized direction
|
||||
* @param bCull: cull back face if true
|
||||
* @return :
|
||||
* @note:
|
||||
* @todo:
|
||||
* @author: kuiwu [8/10/2005]
|
||||
* @ref: Tomas Moller's JGT code
|
||||
*/
|
||||
static bool RayTriangleIntersect(A3DVECTOR3 vOrigin, A3DVECTOR3 vDir, A3DVECTOR3[] vert, ref float t, ref float u, ref float v, bool bCull)
|
||||
{
|
||||
// find vectors for two edges sharing vert0
|
||||
A3DVECTOR3 edge1 = vert[1] - vert[0];
|
||||
A3DVECTOR3 edge2 = vert[2] - vert[0];
|
||||
// begin calculating determinant - also used to calculate U parameter
|
||||
A3DVECTOR3 pvec = A3DVECTOR3.CrossProduct(vDir, edge2);
|
||||
// if determinant is near zero, ray lies in plane of triangle
|
||||
float det = A3DVECTOR3.DotProduct(edge1, pvec);
|
||||
if (bCull)
|
||||
{
|
||||
if (det < LOCAL_EPSILON)
|
||||
return false;
|
||||
// From here, det is > 0.
|
||||
// Calculate distance from vert0 to ray origin
|
||||
A3DVECTOR3 tvec = vOrigin - vert[0];
|
||||
// Calculate U parameter and test bounds
|
||||
u = A3DVECTOR3.DotProduct(tvec, pvec);
|
||||
if ((u < 0.0f) || (u > det))
|
||||
return false;
|
||||
|
||||
// prepare to test V parameter
|
||||
A3DVECTOR3 qvec = A3DVECTOR3.CrossProduct(tvec, edge1);
|
||||
// calculate V parameter and test bounds
|
||||
v = A3DVECTOR3.DotProduct(vDir, qvec);
|
||||
if ((v < 0.0f) || (u + v > det))
|
||||
return false;
|
||||
|
||||
// calculate t, ray intersects triangle
|
||||
t = A3DVECTOR3.DotProduct(edge2, qvec);
|
||||
// Det > 0 so we can early exit here
|
||||
// Intersection point is valid if distance is positive
|
||||
// (else it can just be a face behind the orig point)
|
||||
if (t < 0.0f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
float OneOverDet = 1.0f / det;
|
||||
|
||||
|
||||
t *= OneOverDet;
|
||||
u *= OneOverDet;
|
||||
v *= OneOverDet;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (det > -LOCAL_EPSILON && det < LOCAL_EPSILON)
|
||||
return false;
|
||||
float OneOverDet = 1.0f / det;
|
||||
// Calculate distance from vert0 to ray origin
|
||||
A3DVECTOR3 tvec = vOrigin - vert[0];
|
||||
// calculate U parameter and test bounds
|
||||
u = A3DVECTOR3.DotProduct(tvec, pvec) * OneOverDet;
|
||||
if ((u < 0.0f) || (u > 1.0f))
|
||||
return false;
|
||||
// prepare to test V parameter
|
||||
A3DVECTOR3 qvec = A3DVECTOR3.CrossProduct(tvec, edge1);
|
||||
// calculate V parameter and test bounds
|
||||
v = A3DVECTOR3.DotProduct(vDir, qvec) * OneOverDet;
|
||||
if ((v < 0.0f) || (u + v > 1.0f))
|
||||
return false;
|
||||
// calculate t, ray intersects triangle
|
||||
t = A3DVECTOR3.DotProduct(edge2, qvec) * OneOverDet;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CollideWithTerrain(A3DVECTOR3 vStart, A3DVECTOR3 vDelta, ref float fFraction, ref A3DVECTOR3 vHitNormal, ref bool bStart)
|
||||
{
|
||||
|
||||
CECWorld pWorld = CECWorld.Instance; //g_pGame.GetGameRun().GetWorld();
|
||||
A3DTerrain2 pTerrain = pWorld.GetTerrain();
|
||||
bStart = false;
|
||||
float h1 = pTerrain.GetPosHeight(vStart, ref vHitNormal);
|
||||
if (h1 > vStart.y + 1E-4f )
|
||||
{//start under terrain
|
||||
bStart = true;
|
||||
fFraction = 0.0f;
|
||||
return true;
|
||||
}
|
||||
float h1 = pTerrain.GetPosHeight(vStart, ref vHitNormal);
|
||||
if (h1 > vStart.y + 1E-4f)
|
||||
{//start under terrain
|
||||
bStart = true;
|
||||
fFraction = 0.0f;
|
||||
return true;
|
||||
}
|
||||
|
||||
int nWid, nHei; // in grid, 2 meters
|
||||
int nWid, nHei; // in grid, 2 meters
|
||||
float fMag = vDelta.Magnitude();
|
||||
|
||||
nWid = (int)Math.Ceiling(fMag / 2.0f);
|
||||
nWid = Math.Max(3, nWid);
|
||||
nHei = nWid;
|
||||
int nTriangles = nWid * nHei * 2;
|
||||
int nTriangles = nWid * nHei * 2;
|
||||
A3DVECTOR3[] pVerts = new A3DVECTOR3[(nWid + 1) * (nHei + 1)];
|
||||
//assert(pVerts != NULL);
|
||||
//memset(pVerts, 0, sizeof(A3DVECTOR3)* (nWid + 1) * (nHei + 1));
|
||||
WORD[] pIndices = new WORD[nTriangles * 3];
|
||||
//assert(pIndices != NULL);
|
||||
//memset(pIndices, 0, sizeof(WORD)* nTriangles * 3);
|
||||
if (!pTerrain.GetFacesOfArea(vStart, nWid, nHei, pVerts, pIndices))
|
||||
{
|
||||
//a_freetemp(pVerts);
|
||||
// a_freetemp(pIndices);
|
||||
return false;
|
||||
}
|
||||
//assert(pVerts != NULL);
|
||||
//memset(pVerts, 0, sizeof(A3DVECTOR3)* (nWid + 1) * (nHei + 1));
|
||||
WORD[] pIndices = new WORD[nTriangles * 3];
|
||||
//assert(pIndices != NULL);
|
||||
//memset(pIndices, 0, sizeof(WORD)* nTriangles * 3);
|
||||
if (!pTerrain.GetFacesOfArea(vStart, nWid, nHei, ref pVerts, ref pIndices))
|
||||
{
|
||||
//a_freetemp(pVerts);
|
||||
// a_freetemp(pIndices);
|
||||
return false;
|
||||
}
|
||||
int i;
|
||||
A3DVECTOR3* vert[3];
|
||||
//@note : Here init the fraction. By Kuiwu[9/10/2005]
|
||||
fFraction = 100.0f;
|
||||
float tmpFraction = fFraction;
|
||||
A3DVECTOR3[] vert = new A3DVECTOR3[3];
|
||||
//@note : Here init the fraction. By Kuiwu[9/10/2005]
|
||||
fFraction = 100.0f;
|
||||
float tmpFraction = fFraction;
|
||||
|
||||
for (i = 0; i < nTriangles; i++)
|
||||
{
|
||||
vert[0] = pVerts + pIndices[i * 3];
|
||||
vert[1] = pVerts + pIndices[i * 3 + 1];
|
||||
vert[2] = pVerts + pIndices[i * 3 + 2];
|
||||
A3DVECTOR3 vPt;
|
||||
for (i = 0; i < nTriangles; i++)
|
||||
{
|
||||
vert[0] = pVerts[pIndices[i * 3]];
|
||||
vert[1] = pVerts[pIndices[i * 3 + 1]];
|
||||
vert[2] = pVerts[pIndices[i * 3 + 2]];
|
||||
//A3DVECTOR3 vPt;
|
||||
|
||||
//@note: Tomas Moller's JGT code : By Kuiwu[9/10/2005]
|
||||
//@note: discard the engine version because it put back the hit point too much. By Kuiwu[13/10/2005]
|
||||
// if(CLS_RayToTriangle(vStart, vDelta, *vert[0], *vert[1], *vert[2], vPt, true, &tmpFraction)
|
||||
// && (tmpFraction <= 1.0f) && (tmpFraction < fFraction))
|
||||
if (SegmentTriangleIntersect(vStart, vDelta, vert, tmpFraction, true) && (tmpFraction < fFraction))
|
||||
{
|
||||
//get the triangle normal
|
||||
A3DVECTOR3 vEdge1((* vert[1]) -(*vert[0]) );
|
||||
A3DVECTOR3 vEdge2((* vert[2]) -(*vert[0]) );
|
||||
vHitNormal = CrossProduct(vEdge1, vEdge2);
|
||||
vHitNormal.Normalize();
|
||||
//@note: Tomas Moller's JGT code : By Kuiwu[9/10/2005]
|
||||
//@note: discard the engine version because it put back the hit point too much. By Kuiwu[13/10/2005]
|
||||
// if(CLS_RayToTriangle(vStart, vDelta, *vert[0], *vert[1], *vert[2], vPt, true, &tmpFraction)
|
||||
// && (tmpFraction <= 1.0f) && (tmpFraction < fFraction))
|
||||
if (SegmentTriangleIntersect(vStart, vDelta, vert, ref tmpFraction, true) && (tmpFraction < fFraction))
|
||||
{
|
||||
//get the triangle normal
|
||||
A3DVECTOR3 vEdge1 = vert[1] - vert[0];
|
||||
A3DVECTOR3 vEdge2 = vert[2] - vert[0];
|
||||
vHitNormal = A3DVECTOR3.CrossProduct(vEdge1, vEdge2);
|
||||
vHitNormal.Normalize();
|
||||
|
||||
//@note : may be redundant, but to assure. By Kuiwu[17/10/2005]
|
||||
A3DVECTOR3 vDir;
|
||||
Normalize(vDelta, vDir);
|
||||
if (DotProduct(vHitNormal, vDir) > 0.01f)
|
||||
{//leave the hit plane
|
||||
assert(0 && "hit a plane with same direction!");
|
||||
continue;
|
||||
}
|
||||
//@note : may be redundant, but to assure. By Kuiwu[17/10/2005]
|
||||
A3DVECTOR3 vDir = new A3DVECTOR3();
|
||||
A3DVECTOR3.Normalize(vDelta, out vDir);
|
||||
if (A3DVECTOR3.DotProduct(vHitNormal, vDir) > 0.01f)
|
||||
{//leave the hit plane
|
||||
//assert(0 && "hit a plane with same direction!");
|
||||
continue;
|
||||
}
|
||||
|
||||
fFraction = a_Max(0.0f, tmpFraction);
|
||||
}
|
||||
|
||||
}
|
||||
a_freetemp(pVerts);
|
||||
a_freetemp(pIndices);
|
||||
fFraction = Math.Max(0.0f, tmpFraction);
|
||||
}
|
||||
|
||||
return (fFraction <= 1.0f);
|
||||
}
|
||||
//a_freetemp(pVerts);
|
||||
// a_freetemp(pIndices);
|
||||
|
||||
}
|
||||
return (fFraction <= 1.0f);
|
||||
|
||||
}
|
||||
|
||||
public static bool AABBCollideWithBrush(ref BrushTraceInfo pInfo)
|
||||
{
|
||||
CECWorld pWorld = CECWorld.Instance; //g_pGame.GetGameRun().GetWorld();
|
||||
|
||||
CECOrnamentMan pOrnMan = pWorld.GetOrnamentMan();
|
||||
bool bBrush = pOrnMan.TraceWithBrush(ref pInfo);
|
||||
|
||||
BrushTraceInfo info = pInfo;
|
||||
CECMatterMan pMatterMan = pWorld.GetMatterMan();
|
||||
if (pMatterMan.TraceWithBrush(&info) && info.fFraction < pInfo.fFraction)
|
||||
{
|
||||
*pInfo = info;
|
||||
bBrush = true;
|
||||
}
|
||||
|
||||
info = *pInfo;
|
||||
CECNPCMan* pNPCMan = pWorld.GetNPCMan();
|
||||
if (pNPCMan.TraceWithBrush(&info) && info.fFraction < pInfo.fFraction)
|
||||
{
|
||||
*pInfo = info;
|
||||
bBrush = true;
|
||||
}
|
||||
|
||||
return bBrush;
|
||||
}
|
||||
}
|
||||
public struct OtherPlayer_Move_Info
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user