fix: update logic check bush.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
using CSNetwork.GPDataType;
|
||||
using UnityEngine;
|
||||
using ARectI = BrewMonster.Scripts.ARect<int>;
|
||||
using ARectF = BrewMonster.Scripts.ARect<float>;
|
||||
using BlockArray = System.Collections.Generic.List<BrewMonster.Scripts.World.A3DTerrain2Block>;
|
||||
using BrewMonster.Scripts.Player;
|
||||
using CSNetwork.GPDataType;
|
||||
using System.Linq;
|
||||
using ARectF = BrewMonster.Scripts.ARect<float>;
|
||||
using ARectI = BrewMonster.Scripts.ARect<int>;
|
||||
using BlockArray = System.Collections.Generic.List<BrewMonster.Scripts.World.A3DTerrain2Block>;
|
||||
using WORD = System.UInt16;
|
||||
|
||||
namespace BrewMonster.Scripts.World
|
||||
@@ -26,7 +26,7 @@ namespace BrewMonster.Scripts.World
|
||||
};
|
||||
|
||||
// Terrain2 vertex format when use vertex-light (not lightmap)
|
||||
struct A3DTRN2VERTEX2
|
||||
public struct A3DTRN2VERTEX2
|
||||
{
|
||||
public float vPosX; // Position X
|
||||
public float vPosY; // Position Y
|
||||
@@ -43,8 +43,10 @@ namespace BrewMonster.Scripts.World
|
||||
public bool IsDataLoaded() { return m_bDataLoaded; }
|
||||
public uint m_dwBlockFlags; // Block flags
|
||||
public A3DAABB m_aabbBlock; // Block postion and size in whole world
|
||||
A3DTRN2VERTEX1[] m_aVertices1; // Vertex buffer, ps version
|
||||
A3DTRN2VERTEX2[] m_aVertices2; // Vertex buffer, non-ps version
|
||||
public A3DTRN2VERTEX1[] m_aVertices1; // Vertex buffer, ps version
|
||||
public A3DTRN2VERTEX2[] m_aVertices2; // Vertex buffer, non-ps version
|
||||
public A3DTerrain2 m_pTerrain; // Terrain object
|
||||
public int m_iBlockGrid; // Each block has m_iBlockGrid * m_iBlockGrid terrain grids
|
||||
|
||||
// Get block's position and size in whole world
|
||||
public A3DAABB GetBlockAABB() { return m_aabbBlock; }
|
||||
@@ -65,6 +67,165 @@ namespace BrewMonster.Scripts.World
|
||||
return new A3DVECTOR3(m_aVertices2[n].vPosX, m_aVertices2[n].vPosY, m_aVertices2[n].vPosZ);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy block vertices to destination buffer. This function works like BitBlt.
|
||||
Copy vertex positions in a rectangle grid area to destination buffer, every
|
||||
vertex is like a pixel in BitBlt;
|
||||
|
||||
pDestBuf: destination vertex buffer
|
||||
iWid, iHei: vertex rectangle area's size
|
||||
iDestPitch: destination vertex buffer pitch in A3DVECTOR3
|
||||
sx, sy: grid rectangle area's left-top corner in block
|
||||
*/
|
||||
public bool CopyVertexPos(ref A3DVECTOR3[] pDestBuf, int iWid, int iHei,
|
||||
int iDestPitch, int sx, int sy)
|
||||
{
|
||||
WORD[] aIndexMaps = m_pTerrain.GetLODManager().GetIndexMaps();
|
||||
int pDestLine = 0;
|
||||
int iSrcLine = sy * (m_iBlockGrid + 1) + sx;
|
||||
|
||||
if (m_pTerrain.UseLightmapTech())
|
||||
{
|
||||
//ASSERT(m_aVertices1);
|
||||
|
||||
for (int i = 0; i < iHei; i++)
|
||||
{
|
||||
int destIndex = pDestLine;
|
||||
int iSrc = iSrcLine;
|
||||
pDestLine += iDestPitch;
|
||||
iSrcLine += m_iBlockGrid + 1;
|
||||
|
||||
for (int j = 0; j < iWid; j++, destIndex++, iSrc++)
|
||||
{
|
||||
// Note: here we map index
|
||||
A3DTRN2VERTEX1 pSrc = m_aVertices1[aIndexMaps[iSrc]];
|
||||
|
||||
pDestBuf[destIndex].x = pSrc.vPosX;
|
||||
pDestBuf[destIndex].y = pSrc.vPosY;
|
||||
pDestBuf[destIndex].z = pSrc.vPosZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < iHei; i++)
|
||||
{
|
||||
int pDest = pDestLine;
|
||||
int iSrc = iSrcLine;
|
||||
pDestLine += iDestPitch;
|
||||
iSrcLine += m_iBlockGrid + 1;
|
||||
|
||||
for (int j = 0; j < iWid; j++, pDest++, iSrc++)
|
||||
{
|
||||
var pSrc = m_aVertices2[aIndexMaps[iSrc]];
|
||||
|
||||
pDestBuf[pDest].x = pSrc.vPosX;
|
||||
pDestBuf[pDest].y = pSrc.vPosY;
|
||||
pDestBuf[pDest].z = pSrc.vPosZ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Copy grid faces to destination buffer. This function works like BitBlt.
|
||||
Copy face in a rectangle grid area to destination buffer, every face is
|
||||
like a pixel in BitBlt;
|
||||
|
||||
pDestVert: destination vertex buffer
|
||||
pDestIdx: destination index buffer
|
||||
iWid, iHei: grid rectangle area's size
|
||||
iDstVertPitch: destination vertex buffer pitch in A3DVECTOR3
|
||||
iBaseVert: Index of left-top corner vertex in vertex buffer
|
||||
sx, sy: grid rectangle area's left-top corner in block
|
||||
*/
|
||||
public bool CopyFaces(ref A3DVECTOR3[] pDestVert, ref WORD[] pDestIdx, int iWid, int iHei,
|
||||
int iDstVertPitch, int iBaseVert, int sx, int sy)
|
||||
{
|
||||
// Copy vertices at first. Notice the difference of iWid and iHei in this
|
||||
// function and in CopyVertexPos()
|
||||
CopyVertexPos(ref pDestVert, iWid + 1, iHei + 1, iDstVertPitch, sx, sy);
|
||||
|
||||
// Build indices
|
||||
int pIndices = 0;
|
||||
|
||||
for (int i = 0; i < iHei; i++)
|
||||
{
|
||||
WORD v0 = (WORD)iBaseVert;
|
||||
iBaseVert += iDstVertPitch;
|
||||
|
||||
for (int j = 0; j < iWid; j++, pIndices += 6, v0++)
|
||||
{
|
||||
// v3 v0----v1
|
||||
// | \ \ |
|
||||
// | \ \ |
|
||||
// | \ \ |
|
||||
// | \ \ |
|
||||
// v5---v4 v2
|
||||
pDestIdx[pIndices] = v0;
|
||||
pDestIdx[pIndices + 1] = (WORD)(v0 + 1);
|
||||
pDestIdx[pIndices + 2] = (WORD)(v0 + iDstVertPitch + 1);
|
||||
|
||||
pDestIdx[pIndices + 3] = v0;
|
||||
pDestIdx[pIndices + 4] = (WORD)(v0 + iDstVertPitch + 1);
|
||||
pDestIdx[pIndices + 5] = (WORD)(v0 + iDstVertPitch);
|
||||
}
|
||||
}
|
||||
|
||||
// If this area contain block's right-top corner grid or left-bottom
|
||||
// corner grid, then we have to adjust index so that they are in
|
||||
// rendering order
|
||||
if (sx == 0 && sy + iHei == m_iBlockGrid)
|
||||
{
|
||||
// Contain left-bottom corner grid
|
||||
// v0----v1
|
||||
// | / |
|
||||
// | / |
|
||||
// | / |
|
||||
// | / |
|
||||
// v2----v3
|
||||
int offer = (iHei - 1) * iWid * 6;
|
||||
WORD v0 = pDestIdx[offer];
|
||||
WORD v1 = pDestIdx[offer + 1];
|
||||
WORD v2 = pDestIdx[offer + 5];
|
||||
WORD v3 = pDestIdx[offer + 2];
|
||||
|
||||
pDestIdx[offer] = v0;
|
||||
pDestIdx[offer + 1] = v1;
|
||||
pDestIdx[offer + 2] = v2;
|
||||
|
||||
pDestIdx[offer + 3] = v1;
|
||||
pDestIdx[offer + 4] = v3;
|
||||
pDestIdx[offer + 5] = v2;
|
||||
}
|
||||
|
||||
if (sx + iWid == m_iBlockGrid && sy == 0)
|
||||
{
|
||||
// Contain right-top corner grid
|
||||
// v0----v1
|
||||
// | / |
|
||||
// | / |
|
||||
// | / |
|
||||
// | / |
|
||||
// v2----v3
|
||||
int offer = (iWid - 1) * 6;
|
||||
WORD v0 = pDestIdx[offer];
|
||||
WORD v1 = pDestIdx[offer + 1];
|
||||
WORD v2 = pDestIdx[offer + 5];
|
||||
WORD v3 = pDestIdx[offer + 2];
|
||||
|
||||
pDestIdx[offer + 0] = v0;
|
||||
pDestIdx[offer + 1] = v1;
|
||||
pDestIdx[offer + 2] = v2;
|
||||
|
||||
pDestIdx[offer + 3] = v1;
|
||||
pDestIdx[offer + 4] = v3;
|
||||
pDestIdx[offer + 5] = v2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class A3DTerrain2
|
||||
@@ -75,9 +236,18 @@ namespace BrewMonster.Scripts.World
|
||||
public int m_iBlockGrid = 0; // Each block has m_iBlockGrid * m_iBlockGrid terrain grids
|
||||
public float m_fGridSize; // Terrain grid size (on x and z axis) in logic unit (metres)
|
||||
public A3DTerrain2LOD m_pLODMan; // LOD manager
|
||||
public int m_iNumActBlockRow; // Row and column number of active blocks
|
||||
public int m_iNumAllBlockRow = 0; // Row number of all blocks
|
||||
public int m_iNumAllBlockCol = 0; // Column number of all blocks
|
||||
public bool m_bVertexLight = false; // true, force to use vertex light rather than lightmap
|
||||
|
||||
// Check lightmap or vertex-light is used
|
||||
public bool UseLightmapTech() { return !m_bVertexLight; }
|
||||
|
||||
public A3DTerrain2LOD GetLODManager() { return m_pLODMan; }
|
||||
|
||||
// Get grid faces of specified area
|
||||
public bool GetFacesOfArea(A3DVECTOR3 vCenter, int iGridWid, int iGridLen, A3DVECTOR3 pVertBuf, WORD pIdxBuf)
|
||||
public bool GetFacesOfArea(A3DVECTOR3 vCenter, int iGridWid, int iGridLen, ref A3DVECTOR3[] pVertBuf, ref WORD[] pIdxBuf)
|
||||
{
|
||||
if (m_pCurActBlocks.rcArea.IsEmpty())
|
||||
return false;
|
||||
@@ -90,10 +260,10 @@ namespace BrewMonster.Scripts.World
|
||||
rcGrid.right = rcGrid.left + iGridWid;
|
||||
rcGrid.bottom = rcGrid.top + iGridLen;
|
||||
|
||||
return GetFacesOfArea(rcGrid, pVertBuf, pIdxBuf);
|
||||
return GetFacesOfArea(rcGrid, ref pVertBuf, ref pIdxBuf);
|
||||
}
|
||||
|
||||
public bool GetFacesOfArea(ARectI rcGridArea, A3DVECTOR3 pVertBuf, WORD pIdxBuf)
|
||||
public bool GetFacesOfArea(ARectI rcGridArea, ref A3DVECTOR3[] pVertBuf, ref WORD[] pIdxBuf)
|
||||
{
|
||||
if (m_pCurActBlocks.rcArea.IsEmpty())
|
||||
return false;
|
||||
@@ -126,12 +296,14 @@ namespace BrewMonster.Scripts.World
|
||||
for (c = rcBlock.left; c <= rcBlock.right; c++)
|
||||
{
|
||||
if (!m_pCurActBlocks.rcArea.PtInRect(c, r) ||
|
||||
!m_pCurActBlocks.GetBlock(r, c, false))
|
||||
m_pCurActBlocks.GetBlock(r, c, false) == null)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
WORD pDestIdx = pIdxBuf;
|
||||
int pDestIdx = 0;
|
||||
A3DVECTOR3[] pVertDest = new A3DVECTOR3[0];
|
||||
WORD[] pIdxTemp = new WORD[0];
|
||||
|
||||
for (r = rcBlock.top; r <= rcBlock.bottom; r++)
|
||||
{
|
||||
@@ -152,12 +324,22 @@ namespace BrewMonster.Scripts.World
|
||||
int dx = rc.left - rcGrid.left;
|
||||
int dy = rc.top - rcGrid.top;
|
||||
int iBaseVert = dy * (rcGrid.Width() + 1) + dx;
|
||||
A3DVECTOR3 pVertDest = pVertBuf + iBaseVert;
|
||||
|
||||
pVertDest = pVertBuf.Skip(iBaseVert).ToArray();
|
||||
pIdxTemp = pIdxBuf.Skip(pDestIdx).ToArray();
|
||||
int sx = rc.left - rect.left;
|
||||
int sy = rc.top - rect.top;
|
||||
|
||||
pBlock.CopyFaces(pVertDest, pDestIdx, rc.Width(), rc.Height(), rcGrid.Width() + 1, iBaseVert, sx, sy);
|
||||
pBlock.CopyFaces(ref pVertDest, ref pIdxTemp, rc.Width(), rc.Height(), rcGrid.Width() + 1, iBaseVert, sx, sy);
|
||||
|
||||
for (int i = iBaseVert; i < pVertBuf.Length; i++)
|
||||
{
|
||||
pVertBuf[i] = pVertDest[i - iBaseVert];
|
||||
}
|
||||
for (int i = 0; i < pIdxBuf.Length; i++)
|
||||
{
|
||||
pIdxBuf[i] = pIdxTemp[i - pDestIdx];
|
||||
}
|
||||
|
||||
pDestIdx += rc.Width() * rc.Height() * 6;
|
||||
rect.left += m_iBlockGrid;
|
||||
@@ -252,7 +434,7 @@ namespace BrewMonster.Scripts.World
|
||||
|
||||
if (pvNormal != null)
|
||||
{
|
||||
pvNormal= A3DVECTOR3.CrossProduct(v1 - v0, v2 - v0);
|
||||
pvNormal = A3DVECTOR3.CrossProduct(v1 - v0, v2 - v0);
|
||||
pvNormal.Normalize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
using BrewMonster.Scripts.World;
|
||||
using UnityEngine;
|
||||
using WORD = System.UInt16;
|
||||
|
||||
public class A3DTerrain2LOD
|
||||
{
|
||||
public GRID[] m_aGrids; // Grid of a block
|
||||
public WORD[] m_aIndexMaps; // Index map
|
||||
|
||||
// Get grids
|
||||
public GRID[] GetGrids() { return m_aGrids; }
|
||||
public WORD[] GetIndexMaps() { return m_aIndexMaps; }
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ namespace BrewMonster.Scripts
|
||||
{
|
||||
dynamic l = rc1.left, t = rc1.top, r = rc1.right, b = rc1.bottom;
|
||||
dynamic l2 = rc2.left, t2 = rc2.top, r2 = rc2.right, b2 = rc2.bottom;
|
||||
return new ARect<T>(l + l2, t + t2, r + r2, b + b2);
|
||||
ARect<T> result = new ARect<T>(l + l2, t + t2, r + r2, b + b2);
|
||||
return result;
|
||||
}
|
||||
public static ARect<T> operator -(ARect<T> rc1, ARect<T> rc2)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Managers;
|
||||
using BrewMonster.Scripts.World;
|
||||
using CSNetwork;
|
||||
using CSNetwork.GPDataType;
|
||||
using DG.Tweening;
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Numerics;
|
||||
using UnityEngine;
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
//@desc : using grid to manage the brushes. By Kuiwu[2/11/2005]
|
||||
public class CBrushGrid
|
||||
{
|
||||
//public CBrushGrid(int iCellSize = 80, int iW = 11, int iH = 11);
|
||||
|
||||
// void AddProvider(CBrushProvider* pProvider);
|
||||
// bool RemoveProvider(CBrushProvider* pProvider);
|
||||
// void Build(const A3DVECTOR3& vCenter, bool bForce = false);
|
||||
public bool Trace(BrushTraceInfo pInfo, bool bCheckFlag = true)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if BMAN_VERBOSE_STAT
|
||||
CBManStat * GetStat()
|
||||
{
|
||||
return &m_Stat;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// private int m_iCellSize;
|
||||
// private int m_iW, m_iH; //in cell
|
||||
// private short m_iCenterX, m_iCenterZ;
|
||||
// private float m_fTraceRange2;
|
||||
|
||||
// private CBrushCell m_pBrushCell; //as a brush cell buffer
|
||||
// //@note : use hash table to accelerate searching cell buffer. By Kuiwu[2/11/2005]
|
||||
// private Dictionary<CBrushCell , uint> CellTable;
|
||||
// private CellTable m_CellTbl;
|
||||
|
||||
// private vector<CBrushProvider*> m_UnOrganizedProvider; //to be built.
|
||||
// private vector<CCDBrush*> m_OutOfRangeBrush;
|
||||
|
||||
// private void _GetCellIndex(const A3DVECTOR3& vPos, short& x, short& z);
|
||||
//private CBrushCell * _FindCell(short x, short z);
|
||||
|
||||
// private bool _UpdateCenter(const A3DVECTOR3& vCenter, bool bForce);
|
||||
// private bool _AddBrush(CCDBrush pBrush);
|
||||
#if BMAN_VERBOSE_STAT
|
||||
CBManStat m_Stat;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
public class CECBrushMan
|
||||
{
|
||||
public CBrushGrid m_pBrushGrid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dbb7777494908644db0a9f59f533162d
|
||||
@@ -0,0 +1,98 @@
|
||||
using CSNetwork.GPDataType;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts.Ornament
|
||||
{
|
||||
public class CECOrnamentMan
|
||||
{
|
||||
CECBrushMan m_pBrushMan;
|
||||
// Trace for CD
|
||||
public virtual bool TraceWithBrush(ref BrushTraceInfo pInfo)
|
||||
{
|
||||
bool bCollide = false;
|
||||
//save original result
|
||||
bool bStartSolid = pInfo.bStartSolid; // Collide something at start point
|
||||
bool bAllSolid = pInfo.bAllSolid; // All in something
|
||||
int iClipPlane = pInfo.iClipPlane; // Clip plane's index
|
||||
float fFraction = 100.0f; // Fraction
|
||||
A3DVECTOR3 vNormal = pInfo.ClipPlane.GetNormal(); //clip plane normal
|
||||
float fDist = pInfo.ClipPlane.GetDist(); //clip plane dist
|
||||
|
||||
if (m_pBrushMan != null && m_pBrushMan.Trace(pInfo)
|
||||
&& (pInfo.fFraction < fFraction))
|
||||
{
|
||||
fFraction = pInfo.fFraction;
|
||||
bAllSolid = pInfo.bAllSolid;
|
||||
bStartSolid = pInfo.bStartSolid;
|
||||
iClipPlane = pInfo.iClipPlane;
|
||||
vNormal = pInfo.ClipPlane.GetNormal();
|
||||
fDist = pInfo.ClipPlane.GetDist();
|
||||
bCollide = true;
|
||||
}
|
||||
|
||||
HomeOnmtTable::iterator it1 = m_HomeOrnamentTab.begin();
|
||||
for (; it1 != m_HomeOrnamentTab.end(); ++it1)
|
||||
{
|
||||
CECHomeOrnament* pHomeOrnament = *it1.value();
|
||||
if (!pHomeOrnament.IsLoaded())
|
||||
continue;
|
||||
|
||||
CELBuildingWithBrush* pBuildingWithBrush = pHomeOrnament.GetBuildingWithBrush();
|
||||
if (pBuildingWithBrush && pBuildingWithBrush.TraceWithBrush(pInfo) && (pInfo.fFraction < fFraction))
|
||||
{
|
||||
fFraction = pInfo.fFraction;
|
||||
bAllSolid = pInfo.bAllSolid;
|
||||
bStartSolid = pInfo.bStartSolid;
|
||||
iClipPlane = pInfo.iClipPlane;
|
||||
vNormal = pInfo.ClipPlane.GetNormal();
|
||||
fDist = pInfo.ClipPlane.GetDist();
|
||||
bCollide = true;
|
||||
}
|
||||
}
|
||||
|
||||
// now see if collide with forest
|
||||
CELForest* pForest = g_pGame.GetGameRun().GetWorld().GetForest();
|
||||
if ((fFraction > 0.0f) && pForest
|
||||
&& pForest.TraceWithBrush(pInfo)
|
||||
&& (pInfo.fFraction < fFraction))
|
||||
{
|
||||
fFraction = pInfo.fFraction;
|
||||
bAllSolid = pInfo.bAllSolid;
|
||||
bStartSolid = pInfo.bStartSolid;
|
||||
iClipPlane = pInfo.iClipPlane;
|
||||
vNormal = pInfo.ClipPlane.GetNormal();
|
||||
fDist = pInfo.ClipPlane.GetDist();
|
||||
bCollide = true;
|
||||
}
|
||||
|
||||
// now see if collide with dynamic scene building
|
||||
ECModelTable::iterator it = m_ECModelTab.begin();
|
||||
for (; it != m_ECModelTab.end(); ++it)
|
||||
{
|
||||
ECMODELNODE* pNode = *it.value();
|
||||
if ((fFraction > 0.0f) && pNode
|
||||
&& pNode.TraceWithBrush(pInfo)
|
||||
&& (pInfo.fFraction < fFraction))
|
||||
{
|
||||
fFraction = pInfo.fFraction;
|
||||
bAllSolid = pInfo.bAllSolid;
|
||||
bStartSolid = pInfo.bStartSolid;
|
||||
iClipPlane = pInfo.iClipPlane;
|
||||
vNormal = pInfo.ClipPlane.GetNormal();
|
||||
fDist = pInfo.ClipPlane.GetDist();
|
||||
bCollide = true;
|
||||
}
|
||||
}
|
||||
|
||||
//set back
|
||||
pInfo.fFraction = fFraction;
|
||||
pInfo.bStartSolid = bStartSolid;
|
||||
pInfo.bAllSolid = bAllSolid;
|
||||
pInfo.iClipPlane = iClipPlane;
|
||||
pInfo.ClipPlane.SetNormal(vNormal);
|
||||
pInfo.ClipPlane.SetD(fDist);
|
||||
return bCollide;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90848592c1c53d04e87291f2c1bfafdb
|
||||
@@ -1,4 +1,5 @@
|
||||
using BrewMonster;
|
||||
using BrewMonster.Scripts.Ornament;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
@@ -7,7 +8,7 @@ namespace BrewMonster.Scripts.World
|
||||
public class CECWorld : MonoSingleton<CECWorld>
|
||||
{
|
||||
protected A3DTerrain2 m_pA3DTerrain; // Terrain object
|
||||
|
||||
CECOrnamentMan m_pOnmtMan;
|
||||
uint m_dwBornStamp = 0;
|
||||
|
||||
public uint GetBornStamp() { return m_dwBornStamp++; }
|
||||
@@ -17,5 +18,10 @@ namespace BrewMonster.Scripts.World
|
||||
{
|
||||
return m_pA3DTerrain;
|
||||
}
|
||||
|
||||
public CECOrnamentMan GetOrnamentMan()
|
||||
{
|
||||
return m_pOnmtMan;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+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