fix: update struct in logic terrain.

This commit is contained in:
Tungdv
2025-10-15 18:14:53 +07:00
parent 79a3450e9d
commit de76d2dec0
7 changed files with 673 additions and 115 deletions
+109
View File
@@ -164,6 +164,114 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
_nextSceneName: LoginScene
--- !u!1 &428240946
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 428240950}
- component: {fileID: 428240949}
- component: {fileID: 428240948}
- component: {fileID: 428240947}
m_Layer: 0
m_Name: Cube
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!65 &428240947
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 428240946}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 1, y: 1, z: 1}
m_Center: {x: 0, y: 0, z: 0}
--- !u!23 &428240948
MeshRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 428240946}
m_Enabled: 1
m_CastShadows: 1
m_ReceiveShadows: 1
m_DynamicOccludee: 1
m_StaticShadowCaster: 0
m_MotionVectors: 1
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RayTracingAccelStructBuildFlagsOverride: 0
m_RayTracingAccelStructBuildFlags: 1
m_SmallMeshCulling: 1
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
- {fileID: 2100000, guid: 31321ba15b8f8eb4c954353edc038b1d, type: 2}
m_StaticBatchInfo:
firstSubMesh: 0
subMeshCount: 0
m_StaticBatchRoot: {fileID: 0}
m_ProbeAnchor: {fileID: 0}
m_LightProbeVolumeOverride: {fileID: 0}
m_ScaleInLightmap: 1
m_ReceiveGI: 1
m_PreserveUVs: 0
m_IgnoreNormalsForChartDetection: 0
m_ImportantGI: 0
m_StitchLightmapSeams: 1
m_SelectedEditorRenderState: 3
m_MinimumChartSize: 4
m_AutoUVMaxDistance: 0.5
m_AutoUVMaxAngle: 89
m_LightmapParameters: {fileID: 0}
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &428240949
MeshFilter:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 428240946}
m_Mesh: {fileID: 10202, guid: 0000000000000000e000000000000000, type: 0}
--- !u!4 &428240950
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 428240946}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &506356661
PrefabInstance:
m_ObjectHideFlags: 0
@@ -586,3 +694,4 @@ SceneRoots:
- {fileID: 591506937}
- {fileID: 105404091}
- {fileID: 506356661}
- {fileID: 428240950}
@@ -1,68 +1,185 @@
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 WORD = System.UInt16;
namespace BrewMonster.Scripts.World
{
public class A3DTerrain2
public class A3DTerrain2Block
{
protected ACTBLOCKS[] m_pCurActBlocks; // Currently active block array
// Active blocks
public struct ACTBLOCKS
// Trerrain2 vertex format when use lightmap
public struct A3DTRN2VERTEX1
{
public ARectI rcArea; // Active area represented in blocks
public BlockArray aBlocks; // Active block array
public ACTBLOCKS()
{
aBlocks = new BlockArray[128];
}
ARectI rcArea; // Active area represented in blocks
BlockArray aBlocks; // Active block array
// Get block object at specified row, column.
A3DTerrain2Block* GetBlock(int r, int c, bool bClear)
{
ASSERT(rcArea.PtInRect(c, r));
int iIndex = GetBlockIndex(r, c);
A3DTerrain2Block* pBlock = aBlocks[iIndex];
if (bClear)
aBlocks[iIndex] = NULL;
return pBlock;
}
// Set block object at specified row, column
void SetBlock(int r, int c, A3DTerrain2Block* pBlock)
{
ASSERT(rcArea.PtInRect(c, r));
int iIndex = GetBlockIndex(r, c);
aBlocks[iIndex] = pBlock;
}
// Get block index in aBlocks
int GetBlockIndex(int r, int c)
{
return (r - rcArea.top) * rcArea.Width() + c - rcArea.left;
}
public float vPosX; // PositionX
public float vPosY; // PositionY
public float vPosZ; // PositionZ
public float vNormalX; // NormalX
public float vNormalY; // NormalY
public float vNormalZ; // NormalZ
public float u1, v1; // Texture coordinates project on xz
public float u2, v2; // Texture coordinates project on xy
public float u3, v3; // Texture coordinates project on yz
public float u4, v4; // Texture coordinate of layer mask
};
// Terrain2 vertex format when use vertex-light (not lightmap)
struct A3DTRN2VERTEX2
{
public float vPosX; // Position X
public float vPosY; // Position Y
public float vPosZ; // Position Z
public uint dwDiffuse; // Diffuse color
public uint dwSpecular; // Specular color
public float u1, v1; // Texture coordinates project on xz
public float u2, v2; // Texture coordinates project on xy
public float u3, v3; // Texture coordinates project on yz
public float u4, v4; // Texture coordinate of layer mask
};
public bool m_bDataLoaded = false; // Data loaded flag
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
// Get block's position and size in whole world
public A3DAABB GetBlockAABB() { return m_aabbBlock; }
// Get flag for this whole block unable for GetPosHeight
public bool IsNoPosHeight()
{
return (m_dwBlockFlags & Block_flags_masks.T2BKFLAG_NOPOSHEIGHT) != 0;
}
// Get vertex
public A3DVECTOR3 GetVertexPos(int n)
{
if (m_aVertices1 != null && m_aVertices1.Length > n)
return new A3DVECTOR3(m_aVertices1[n].vPosX, m_aVertices1[n].vPosY, m_aVertices1[n].vPosZ);
else
{
//ASSERT(m_aVertices2);
return new A3DVECTOR3(m_aVertices2[n].vPosX, m_aVertices2[n].vPosY, m_aVertices2[n].vPosZ);
}
}
}
public class A3DTerrain2
{
public ACTBLOCKS m_pCurActBlocks; // Currently active block array
public ARectF m_rcTerrain; // Whole terrain area in logic unit (metres)
public float m_fBlockSize = 0; // Block size (on x and z axis) in logic unit (metres)
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
// Get grid faces of specified area
public bool GetFacesOfArea(A3DVECTOR3 vCenter, int iGridWid, int iGridLen, A3DVECTOR3 pVertBuf, WORD pIdxBuf)
{
if (m_pCurActBlocks.rcArea.IsEmpty())
return false;
float fInvGridSize = 1.0f / m_fGridSize;
ARectI rcGrid = new ARectI();
rcGrid.left = (int)((vCenter.x - m_rcTerrain.left) * fInvGridSize) - (iGridWid >> 1);
rcGrid.top = (int)((m_rcTerrain.top - vCenter.z) * fInvGridSize) - (iGridLen >> 1);
rcGrid.right = rcGrid.left + iGridWid;
rcGrid.bottom = rcGrid.top + iGridLen;
return GetFacesOfArea(rcGrid, pVertBuf, pIdxBuf);
}
public bool GetFacesOfArea(ARectI rcGridArea, A3DVECTOR3 pVertBuf, WORD pIdxBuf)
{
if (m_pCurActBlocks.rcArea.IsEmpty())
return false;
float fInvGridSize = 1.0f / m_fGridSize;
ARectI rcGrid = rcGridArea;
int iMaxGrid = m_iNumAllBlockCol * m_iBlockGrid;
AAssist.a_Clamp(ref rcGrid.left, 0, iMaxGrid);
AAssist.a_Clamp(ref rcGrid.right, 0, iMaxGrid);
iMaxGrid = m_iNumAllBlockRow * m_iBlockGrid;
AAssist.a_Clamp(ref rcGrid.top, 0, iMaxGrid);
AAssist.a_Clamp(ref rcGrid.bottom, 0, iMaxGrid);
if (rcGrid.IsEmpty())
return false;
ARectI rcBlock = new ARectI();
rcBlock.left = rcGrid.left / m_iBlockGrid;
rcBlock.top = rcGrid.top / m_iBlockGrid;
rcBlock.right = (rcGrid.right - 1) / m_iBlockGrid;
rcBlock.bottom = (rcGrid.bottom - 1) / m_iBlockGrid;
int r, c;
// Ensure all blocks in active area and have been loaded
for (r = rcBlock.top; r <= rcBlock.bottom; r++)
{
for (c = rcBlock.left; c <= rcBlock.right; c++)
{
if (!m_pCurActBlocks.rcArea.PtInRect(c, r) ||
!m_pCurActBlocks.GetBlock(r, c, false))
return false;
}
}
WORD pDestIdx = pIdxBuf;
for (r = rcBlock.top; r <= rcBlock.bottom; r++)
{
ARectI rect = new ARectI();
rect.left = rcBlock.left * m_iBlockGrid;
rect.top = r * m_iBlockGrid;
rect.right = rect.left + m_iBlockGrid;
rect.bottom = rect.top + m_iBlockGrid;
for (c = rcBlock.left; c <= rcBlock.right; c++)
{
A3DTerrain2Block pBlock = m_pCurActBlocks.GetBlock(r, c, false);
//ASSERT(pBlock);
ARectI rc = rcGrid & rect;
//ASSERT(!rc.IsEmpty());
int dx = rc.left - rcGrid.left;
int dy = rc.top - rcGrid.top;
int iBaseVert = dy * (rcGrid.Width() + 1) + dx;
A3DVECTOR3 pVertDest = pVertBuf + iBaseVert;
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);
pDestIdx += rc.Width() * rc.Height() * 6;
rect.left += m_iBlockGrid;
rect.right += m_iBlockGrid;
}
}
return true;
}
// Get height and normal of specified position
public float GetPosHeight(A3DVECTOR3 vPos, A3DVECTOR3? pvNormal = null)
public float GetPosHeight(A3DVECTOR3 vPos, ref A3DVECTOR3 pvNormal)
{
// Give a default value to normal
if (pvNormal.HasValue)
pvNormal.Value.Clear();
if (pvNormal != null)
pvNormal.Clear();
if (m_pCurActBlocks.rcArea.IsEmpty())
return 0.0f;
// Currenly active area AABB
ARectF rcActive;
ARectF rcActive = new ARectF();
rcActive.left = m_rcTerrain.left + m_pCurActBlocks.rcArea.left * m_fBlockSize;
rcActive.top = m_rcTerrain.top - m_pCurActBlocks.rcArea.top * m_fBlockSize;
rcActive.right = rcActive.left + m_pCurActBlocks.rcArea.Width() * m_fBlockSize;
@@ -76,12 +193,12 @@ namespace BrewMonster.Scripts.World
float fInvBlockSize = 1.0f / m_fBlockSize;
int iCol = (int)((vPos.x - rcActive.left) * fInvBlockSize);
int iRow = (int)(-(vPos.z - rcActive.top) * fInvBlockSize);
a_Clamp(iCol, 0, m_pCurActBlocks.rcArea.Width() - 1);
a_Clamp(iRow, 0, m_pCurActBlocks.rcArea.Height() - 1);
AAssist.a_Clamp(ref iCol, 0, m_pCurActBlocks.rcArea.Width() - 1);
AAssist.a_Clamp(ref iRow, 0, m_pCurActBlocks.rcArea.Height() - 1);
int iBlock = iRow * m_pCurActBlocks.rcArea.Width() + iCol;
A3DTerrain2Block* pBlock = m_pCurActBlocks.aBlocks[iBlock];
if (!pBlock || !pBlock.IsDataLoaded())
A3DTerrain2Block pBlock = m_pCurActBlocks.aBlocks[iBlock];
if (pBlock == null || !pBlock.IsDataLoaded())
return 0.0f;
// If whole block is a hole, return as if there is no block here
@@ -89,17 +206,17 @@ namespace BrewMonster.Scripts.World
return 0.0f;
// Get block's AABB
const A3DAABB&aabb = pBlock.GetBlockAABB();
A3DAABB aabb = pBlock.GetBlockAABB();
// Get grid this position is in
float fInvGridSize = 1.0f / m_fGridSize;
iCol = (int)((vPos.x - aabb.Mins.x) * fInvGridSize);
iRow = (int)(-(vPos.z - aabb.Maxs.z) * fInvGridSize);
a_Clamp(iCol, 0, m_iBlockGrid - 1);
a_Clamp(iRow, 0, m_iBlockGrid - 1);
AAssist.a_Clamp(ref iCol, 0, m_iBlockGrid - 1);
AAssist.a_Clamp(ref iRow, 0, m_iBlockGrid - 1);
int iGrid = iRow * m_iBlockGrid + iCol;
const A3DTerrain2LOD::GRID&Grid = m_pLODMan.GetGrids()[iGrid];
GRID Grid = m_pLODMan.GetGrids()[iGrid];
A3DVECTOR3 v0 = pBlock.GetVertexPos(Grid.v0);
A3DVECTOR3 v1 = pBlock.GetVertexPos(Grid.v1);
@@ -122,9 +239,9 @@ namespace BrewMonster.Scripts.World
vDest = v5 + (v4 - v5) * (dx / (v4.x - v5.x));
vDest += (v3 - v4) * (dz / (v3.z - v4.z));
if (pvNormal)
if (pvNormal != null)
{
pvNormal.CrossProduct(v4 - v3, v5 - v3);
pvNormal = A3DVECTOR3.CrossProduct(v4 - v3, v5 - v3);
pvNormal.Normalize();
}
}
@@ -133,9 +250,9 @@ namespace BrewMonster.Scripts.World
vDest = v2 + (v0 - v2) * (dz / (v0.z - v2.z));
vDest += (v1 - v0) * (dx / (v1.x - v0.x));
if (pvNormal)
if (pvNormal != null)
{
pvNormal.CrossProduct(v1 - v0, v2 - v0);
pvNormal= A3DVECTOR3.CrossProduct(v1 - v0, v2 - v0);
pvNormal.Normalize();
}
}
@@ -150,9 +267,9 @@ namespace BrewMonster.Scripts.World
vDest = v0 + (v1 - v0) * (dx / (v1.x - v0.x));
vDest += (v2 - v1) * (dz / (v2.z - v1.z));
if (pvNormal)
if (pvNormal != null)
{
pvNormal.CrossProduct(v1 - v0, v2 - v0);
pvNormal = A3DVECTOR3.CrossProduct(v1 - v0, v2 - v0);
pvNormal.Normalize();
}
}
@@ -161,9 +278,9 @@ namespace BrewMonster.Scripts.World
vDest = v3 + (v5 - v3) * (dz / (v5.z - v3.z));
vDest += (v4 - v5) * (dx / (v4.x - v5.x));
if (pvNormal)
if (pvNormal != null)
{
pvNormal.CrossProduct(v4 - v3, v5 - v3);
pvNormal = A3DVECTOR3.CrossProduct(v4 - v3, v5 - v3);
pvNormal.Normalize();
}
}
@@ -172,4 +289,62 @@ namespace BrewMonster.Scripts.World
return vDest.y;
}
}
// Active blocks
public struct ACTBLOCKS
{
public ARectI rcArea; // Active area represented in blocks
public BlockArray aBlocks; // Active block array
public ACTBLOCKS(ARectI rcArea, BlockArray aBlocks)
{
this.rcArea = rcArea;
this.aBlocks = aBlocks;
}
// Get block object at specified row, column.
public A3DTerrain2Block GetBlock(int r, int c, bool bClear)
{
//ASSERT(rcArea.PtInRect(c, r));
int iIndex = GetBlockIndex(r, c);
A3DTerrain2Block pBlock = aBlocks[iIndex];
if (bClear)
aBlocks[iIndex] = null;
return pBlock;
}
// Set block object at specified row, column
void SetBlock(int r, int c, A3DTerrain2Block pBlock)
{
//ASSERT(rcArea.PtInRect(c, r));
int iIndex = GetBlockIndex(r, c);
aBlocks[iIndex] = pBlock;
}
// Get block index in aBlocks
int GetBlockIndex(int r, int c)
{
return (r - rcArea.top) * rcArea.Width() + c - rcArea.left;
}
};
// Block flags & masks
public class Block_flags_masks
{
public static uint T2BKFLAG_DEFAULT = 0x00, // The block flag default value
T2BKFLAG_NORENDER = 0x01, // The whole block is not rendered
T2BKFLAG_NOTRACE = 0x02, // The whole block is out of RayTrace
T2BKFLAG_NOPOSHEIGHT = 0x04, // The whole block is unable to GetPosHeight
T2BKFLAG_NORENDERWITHWATER = 0x08; // The whole block is not rendered with water
};
// Vertex indices in a terrain grid
public struct GRID
{
public int v0, v1, v2; // Face 1
public int v3, v4, v5; // Face 2
};
}
@@ -0,0 +1,9 @@
using BrewMonster.Scripts.World;
using UnityEngine;
public class A3DTerrain2LOD
{
public GRID[] m_aGrids; // Grid of a block
// Get grids
public GRID[] GetGrids() { return m_aGrids; }
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ea4c2d97d77797548b9de5443e250290
@@ -0,0 +1,280 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace BrewMonster.Scripts
{
public class ARect<T> where T : IComparable<T>
{
public T left, top, right, bottom;
public ARect()
{
left = default(T);
top = default(T);
right = default(T);
bottom = default(T);
}
public ARect(ARect<T> rc)
{
left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom;
}
public ARect(T left, T top, T right, T bottom)
{
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
// == and != operator
public static bool operator !=(ARect<T> rc1, ARect<T> rc2)
{
return !(rc1 == rc2);
}
public static bool operator ==(ARect<T> rc1, ARect<T> rc2)
{
return EqualityComparer<T>.Default.Equals(rc1.left, rc2.left) &&
EqualityComparer<T>.Default.Equals(rc1.top, rc2.top) &&
EqualityComparer<T>.Default.Equals(rc1.right, rc2.right) &&
EqualityComparer<T>.Default.Equals(rc1.bottom, rc2.bottom);
}
// + and - operator
public static ARect<T> operator +(ARect<T> rc1, ARect<T> rc2)
{
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);
}
public static ARect<T> operator -(ARect<T> rc1, ARect<T> rc2)
{
return new ARect<T>((dynamic)rc1.left - (dynamic)rc2.left,
(dynamic)rc1.top - (dynamic)rc2.top,
(dynamic)rc1.right - (dynamic)rc2.right,
(dynamic)rc1.bottom - (dynamic)rc2.bottom);
}
//public static ARect<T> operator +(ARect<T> rc1, APoint<T> pt)
//{
// return new ARect<T>((dynamic)rc1.left + (dynamic)pt.x,
// (dynamic)rc1.top + (dynamic)pt.y,
// (dynamic)rc1.right + (dynamic)pt.x,
// (dynamic)rc1.bottom + (dynamic)pt.y);
//}
//public static ARect<T> operator -(ARect<T> rc1, APoint<T> pt)
//{
// return new ARect<T>((dynamic)rc1.left - (dynamic)pt.x,
// (dynamic)rc1.top - (dynamic)pt.y,
// (dynamic)rc1.right - (dynamic)pt.x,
// (dynamic)rc1.bottom - (dynamic)pt.y);
//}
// &= and |= operator
public ARect<T> AndAssign(ARect<T> rc) => this & rc;
public ARect<T> OrAssign(ARect<T> rc) => this | rc;
public static ARect<T> operator &(ARect<T> rc1, ARect<T> rc2)
{
if (rc1.IsEmpty() || rc2.IsEmpty())
return new ARect<T>(default, default, default, default);
dynamic l1 = rc1.left, r1 = rc1.right, t1 = rc1.top, b1 = rc1.bottom;
dynamic l2 = rc2.left, r2 = rc2.right, t2 = rc2.top, b2 = rc2.bottom;
if (l1 >= r2 || l2 >= r1 ||
t1 >= b2 || t2 >= b1)
return new ARect<T>(default, default, default, default);
return new ARect<T>(l1 > l2 ? l1 : l2,
t1 > t2 ? t1 : t2,
r1 < r2 ? r1 : r2,
b1 < b2 ? b1 : b2);
}
public static ARect<T> operator |(ARect<T> rc1, ARect<T> rc2)
{
if (rc1.IsEmpty())
return rc2;
if (rc2.IsEmpty())
return rc1;
dynamic l1 = rc1.left, r1 = rc1.right, t1 = rc1.top, b1 = rc1.bottom;
dynamic l2 = rc2.left, r2 = rc2.right, t2 = rc2.top, b2 = rc2.bottom;
return new ARect<T>(l1 < l2 ? l1 : l2,
t1 < t2 ? t1 : t2,
r1 > r2 ? r1 : r2,
b1 > b2 ? b1 : b2);
}
public static ARect<T> operator +(ARect<T> rc) { return rc; }
public static ARect<T> operator -(ARect<T> rc)
{
return new ARect<T>(-(dynamic)rc.left, -(dynamic)rc.top, -(dynamic)rc.right, -(dynamic)rc.bottom);
}
// = operator
//public static ARect<T> operator = (ARect<T> rc) { left = rc.left; top = rc.top; right = rc.right; bottom = rc.bottom; return *this; }
// += and -= operator
public ARect<T> AdditionAssign(ARect<T> rc)
{
left += (dynamic)rc.left;
top += (dynamic)rc.top;
right += (dynamic)rc.right;
bottom += (dynamic)rc.bottom;
return this;
}
public ARect<T> SubtractionAssign(ARect<T> rc)
{
left -= (dynamic)rc.left;
top -= (dynamic)rc.top;
right -= (dynamic)rc.right;
bottom -= (dynamic)rc.bottom;
return this;
}
//public ARect<T> AdditionAssign(APoint<T> pt) { left += pt.x; top += pt.y; right += pt.x; bottom += pt.y; return this; }
//public ARect<T> SubtractionAssign(APoint<T> pt) { left -= pt.x; top -= pt.y; right -= pt.x; bottom -= pt.y; return this; }
// Get width of rectangle
public T Width()
{
return (dynamic)right - (dynamic)left;
}
// Get height of rectangle
public T Height()
{
return (dynamic)bottom - (dynamic)top;
}
// Get center point of rectangle
//public APoint<T> CenterPoint() { return new APoint<T>((left + right) / 2, (top + bottom) / 2); }
// Set rectangle value
public void SetRect(T _left, T _top, T _right, T _bottom)
{
left = _left;
top = _top;
right = _right;
bottom = _bottom;
}
// Point in rectangle
public bool PtInRect(T x, T y)
{
dynamic valueX = x;
dynamic valueY = y;
return (valueX >= left && valueX < right && valueY >= top && valueY < bottom) ? true : false;
}
//public bool PtInRect(APoint<T> pt) { return PtInRect(pt.x, pt.y); }
// Normalize rectangle. Note: The following CRect member functions require
// normalized rectangles in order to work properly: Height, Width, Size,
// IsEmpty, PtInRect, SetUnion, SetIntersect, operator ==, operator !=,
// operator |, operator |=, operator &, and operator &=
void Normalize()
{
if ((dynamic)left > right)
a_Swap(left, right);
if ((dynamic)top > bottom)
a_Swap(top, bottom);
}
private void a_Swap(T lhs, T rhs)
{
T tmp;
tmp = lhs;
lhs = rhs;
rhs = tmp;
}
// All members are 0 ?
public bool IsRectNull()
{
return ((dynamic)left == 0 && (dynamic)top == 0 && (dynamic)right == 0 && (dynamic)bottom == 0);
}
// Rectangle is empty ?
public bool IsEmpty()
{
return ((dynamic)Width() == 0 || (dynamic)Height() == 0);
}
// Set all members to 0
public void Clear()
{
left = top = right = bottom = default(T);
}
// Deflate rectangle
public void Deflate(T x, T y)
{
left += (dynamic)x;
top += (dynamic)y;
right -= (dynamic)x;
bottom -= (dynamic)y;
}
public void Deflate(ARect<T> rc)
{
left += (dynamic)rc.left;
top += (dynamic)rc.top;
right -= (dynamic)rc.right;
bottom -= (dynamic)rc.bottom;
}
public void Deflate(T l, T t, T r, T b)
{
left += (dynamic)l;
top += (dynamic)t;
right -= (dynamic)r;
bottom -= (dynamic)b;
}
// Inflate rectangle
public void Inflate(T x, T y)
{
left -= (dynamic)x;
top -= (dynamic)y;
right += (dynamic)x;
bottom += (dynamic)y;
}
public void Inflate(ARect<T> rc)
{
left -= (dynamic)rc.left;
top -= (dynamic)rc.top;
right += (dynamic)rc.right;
bottom += (dynamic)rc.bottom;
}
public void Inflate(T l, T t, T r, T b)
{
left -= (dynamic)l;
top -= (dynamic)t;
right += (dynamic)r;
bottom += (dynamic)b;
}
// Offset rectangle
public void Offset(T x, T y)
{
left += (dynamic)x;
top += (dynamic)y;
right += (dynamic)x;
bottom += (dynamic)y;
}
//public void Offset(APoint<T> pt) { this += pt; }
// Set rectangle as union result
public void SetUnion(ARect<T> rc1, ARect<T> rc2)
{
var result = rc1 | rc2;
left = result.left;
right = result.right;
bottom = result.bottom;
top = result.top;
}
// Set rectangle as intersect result
public void SetIntersect(ARect<T> rc1, ARect<T> rc2)
{
var result = rc1 & rc2;
left = result.left;
right = result.right;
bottom = result.bottom;
top = result.top;
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 00eedf309b0008346a58412f4aad4dec
+33 -52
View File
@@ -1,6 +1,8 @@
using CSNetwork.GPDataType;
using UnityEditor.PackageManager;
using BrewMonster.Scripts.World;
using CSNetwork.GPDataType;
using System;
using UnityEngine;
using WORD = System.UInt16;
namespace BrewMonster.Scripts
{
@@ -312,38 +314,37 @@ namespace BrewMonster.Scripts
bool CollideWithTerrain(A3DVECTOR3 vStart, A3DVECTOR3 vDelta, ref float fFraction, ref A3DVECTOR3 vHitNormal, ref bool bStart)
{
CECWorld pWorld = g_pGame.GetGameRun().GetWorld();
A3DTerrain2 pTerrain = pWorld.GetTerrain();
bStart = false;
float h1 = pTerrain.GetPosHeight(vStart, &vHitNormal);
if (h1 > vStart.y + 1E-4f )
{//start under terrain
bStart = true;
fFraction = 0.0f;
return true;
}
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;
}
int nWid, nHei; // in grid, 2 meters
float fMag = vDelta.Magnitude();
int nWid, nHei; // in grid, 2 meters
float fMag = vDelta.Magnitude();
nWid = (int) ceil(fMag / 2.0f);
nWid = a_Max(3, nWid);
nHei = nWid;
int nTriangles = nWid * nHei * 2;
A3DVECTOR3* pVerts = (A3DVECTOR3*)a_malloctemp(sizeof(A3DVECTOR3) * ((nWid + 1) * (nHei + 1)));
assert(pVerts != NULL);
memset(pVerts, 0, sizeof(A3DVECTOR3)* (nWid + 1) * (nHei + 1));
WORD* pIndices = (WORD*)a_malloctemp(sizeof(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;
}
int i;
nWid = (int)Math.Ceiling(fMag / 2.0f);
nWid = Math.Max(3, nWid);
nHei = nWid;
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;
}
int i;
A3DVECTOR3* vert[3];
//@note : Here init the fraction. By Kuiwu[9/10/2005]
fFraction = 100.0f;
@@ -384,26 +385,6 @@ fFraction = a_Max(0.0f, tmpFraction);
a_freetemp(pVerts);
a_freetemp(pIndices);
# ifdef CDR_DEBUG
// if (fFraction <= 1.0f)
// {
// A3DVECTOR3 vHitPos(vStart + vDelta * fFraction);
// A3DVECTOR3 vTerNormal;
// float fH2 = pTerrain.GetPosHeight(vHitPos, &vTerNormal);
// sprintf(msg, "terrain hit %f %f %f normal %f %f %f trcNormal %f %f %f fFraction %f\n", vHitPos.x, vHitPos.y, vHitPos.z,
// vHitNormal.x, vHitNormal.y, vHitNormal.z, vTerNormal.x, vTerNormal.y, vTerNormal.z, fFraction);
// OUTPUT_DEBUG_INFO(msg);
//
// //vHitNormal = vTerNormal;
// }
// else
// {
// A3DVECTOR3 vEnd(vStart + vDelta);
// float fH2 = pTerrain.GetPosHeight(vEnd);
// sprintf(msg, "terrain test clear %f %f %f height %f\n", vEnd.x, vEnd.y, vEnd.z,fH2);
// OUTPUT_DEBUG_INFO(msg);
// }
#endif
return (fFraction <= 1.0f);
}