Core/Entities: Phasing rewrite

This commit is contained in:
hondacrx
2018-03-28 11:09:30 -04:00
parent caad52f636
commit fa35d60f60
72 changed files with 2254 additions and 1146 deletions
+4 -4
View File
@@ -227,22 +227,22 @@ namespace Game.Collision
public class DynamicTreeIntersectionCallback : WorkerCallback
{
public DynamicTreeIntersectionCallback(List<uint> phases)
public DynamicTreeIntersectionCallback(PhaseShift phaseShift)
{
_didHit = false;
_phases = phases;
_phaseShift = phaseShift;
}
public override bool Invoke(Ray r, IModel obj, ref float distance)
{
_didHit = obj.IntersectRay(r, ref distance, true, _phases);
_didHit = obj.IntersectRay(r, ref distance, true, _phaseShift);
return _didHit;
}
public bool didHit() { return _didHit; }
bool _didHit;
List<uint> _phases;
PhaseShift _phaseShift;
}
+8 -8
View File
@@ -57,17 +57,17 @@ namespace Game.Collision
impl.update(diff);
}
public bool getIntersectionTime(List<uint> phases, Ray ray, Vector3 endPos, float maxDist)
public bool getIntersectionTime(Ray ray, Vector3 endPos, PhaseShift phaseShift, float maxDist)
{
float distance = maxDist;
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phases);
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phaseShift);
impl.intersectRay(ray, callback, ref distance, endPos);
if (callback.didHit())
maxDist = distance;
return callback.didHit();
}
public bool getObjectHitPos(List<uint> phases, Vector3 startPos, Vector3 endPos, ref Vector3 resultHitPos, float modifyDist)
public bool getObjectHitPos(Vector3 startPos, Vector3 endPos, ref Vector3 resultHitPos, float modifyDist, PhaseShift phaseShift)
{
bool result = false;
float maxDist = (endPos - startPos).magnitude();
@@ -82,7 +82,7 @@ namespace Game.Collision
Vector3 dir = (endPos - startPos) / maxDist; // direction with length of 1
Ray ray = new Ray(startPos, dir);
float dist = maxDist;
if (getIntersectionTime(phases, ray, endPos, dist))
if (getIntersectionTime(ray, endPos, phaseShift, dist))
{
resultHitPos = startPos + dir * dist;
if (modifyDist < 0)
@@ -105,7 +105,7 @@ namespace Game.Collision
return result;
}
public bool isInLineOfSight(Vector3 startPos, Vector3 endPos, List<uint> phases)
public bool isInLineOfSight(Vector3 startPos, Vector3 endPos, PhaseShift phaseShift)
{
float maxDist = (endPos - startPos).magnitude();
@@ -113,17 +113,17 @@ namespace Game.Collision
return true;
Ray r = new Ray(startPos, (endPos - startPos) / maxDist);
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phases);
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phaseShift);
impl.intersectRay(r, callback, ref maxDist, endPos);
return !callback.didHit();
}
public float getHeight(float x, float y, float z, float maxSearchDist, List<uint> phases)
public float getHeight(float x, float y, float z, float maxSearchDist, PhaseShift phaseShift)
{
Vector3 v = new Vector3(x, y, z + 0.5f);
Ray r = new Ray(v, new Vector3(0, 0, -1));
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phases);
DynamicTreeIntersectionCallback callback = new DynamicTreeIntersectionCallback(phaseShift);
impl.intersectZAllignedRay(r, callback, ref maxSearchDist);
if (callback.didHit())
+164 -122
View File
@@ -36,23 +36,39 @@ namespace Game.Collision
public static string VMapPath = Global.WorldMgr.GetDataPath() + "/vmaps/";
public void Initialize(MultiMap<uint, uint> mapData)
{
iChildMapData = mapData;
foreach (var pair in mapData)
iParentMapData[pair.Value] = pair.Key;
}
public VMAPLoadResult loadMap(uint mapId, uint x, uint y)
{
var result = VMAPLoadResult.Ignored;
if (_loadMap(mapId, x, y))
result = VMAPLoadResult.OK;
else
result = VMAPLoadResult.Error;
if (isMapLoadingEnabled())
{
if (loadSingleMap(mapId, x, y))
{
result = VMAPLoadResult.OK;
var childMaps = iChildMapData.LookupByKey(mapId);
foreach (uint childMapId in childMaps)
if (!loadSingleMap(childMapId, x, y))
result = VMAPLoadResult.Error;
}
else
result = VMAPLoadResult.Error;
}
return result;
}
bool _loadMap(uint mapId, uint tileX, uint tileY)
bool loadSingleMap(uint mapId, uint tileX, uint tileY)
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree == null)
{
string filename = string.Format("{0}{1:D4}.vmtree", VMapPath, mapId);
string filename = VMapPath + getMapFileName(mapId);
StaticMapTree newTree = new StaticMapTree(mapId);
if (!newTree.InitMap(filename, this))
return false;
@@ -65,72 +81,90 @@ namespace Game.Collision
return instanceTree.LoadMapTile(tileX, tileY, this);
}
public WorldModel acquireModelInstance(string filename)
public void unloadMap(uint mapId, uint x, uint y)
{
var model = iLoadedModelFiles.LookupByKey(filename);
if (model == null)
var childMaps = iChildMapData.LookupByKey(mapId);
foreach (uint childMapId in childMaps)
unloadSingleMap(childMapId, x, y);
unloadSingleMap(mapId, x, y);
}
void unloadSingleMap(uint mapId, uint x, uint y)
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
WorldModel worldmodel = new WorldModel();
if (!worldmodel.readFile(VMapPath + filename + ".vmo"))
instanceTree.UnloadMapTile(x, y, this);
if (instanceTree.numLoadedTiles() == 0)
{
Log.outError(LogFilter.Server, "VMapManager: could not load '{0}.vmo'", filename);
return null;
iInstanceMapTrees.Remove(mapId);
}
Log.outDebug(LogFilter.Maps, "VMapManager: loading file '{0}'", filename);
iLoadedModelFiles.Add(filename, new ManagedModel());
model = iLoadedModelFiles.LookupByKey(filename);
model.setModel(worldmodel);
}
model.incRefCount();
return model.getModel();
}
public void releaseModelInstance(string filename)
public void unloadMap(uint mapId)
{
var model = iLoadedModelFiles.LookupByKey(filename);
if (model == null)
var childMaps = iChildMapData.LookupByKey(mapId);
foreach (uint childMapId in childMaps)
unloadSingleMap(childMapId);
unloadSingleMap(mapId);
}
void unloadSingleMap(uint mapId)
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
Log.outError(LogFilter.Server, "VMapManager: trying to unload non-loaded file '{0}'", filename);
return;
instanceTree.UnloadMap(this);
if (instanceTree.numLoadedTiles() == 0)
{
iInstanceMapTrees.Remove(mapId);
}
}
if (model.decRefCount() == 0)
}
public bool isInLineOfSight(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2)
{
if (!isLineOfSightCalcEnabled() || Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
return true;
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
Log.outDebug(LogFilter.Maps, "VMapManager: unloading file '{0}'", filename);
iLoadedModelFiles.Remove(filename);
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
if (pos1 != pos2)
return instanceTree.isInLineOfSight(pos1, pos2);
}
return true;
}
public bool existsMap(uint mapId, uint x, uint y)
public bool getObjectHitPos(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2, out float rx, out float ry, out float rz, float modifyDist)
{
return StaticMapTree.CanLoadMap(VMapPath, mapId, x, y);
}
public static string getMapFileName(uint mapId)
{
return string.Format("{0:D4}.vmtree", mapId);
}
public bool GetLiquidLevel(uint mapId, float x, float y, float z, byte reqLiquidType, ref float level, ref float floor, ref uint type)
{
if (!Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLiquidStatus))
if (isLineOfSightCalcEnabled() && !Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
LocationInfo info = new LocationInfo();
Vector3 pos = convertPositionToInternalRep(x, y, z);
if (instanceTree.GetLocationInfo(pos, info))
{
floor = info.ground_Z;
Contract.Assert(floor < float.MaxValue);
type = info.hitModel.GetLiquidType(); // entry from LiquidType.dbc
if (reqLiquidType != 0 && !Convert.ToBoolean(Global.DB2Mgr.GetLiquidFlags(type) & reqLiquidType))
return false;
if (info.hitInstance.GetLiquidLevel(pos, info, ref level))
return true;
}
Vector3 resultPos;
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
bool result = instanceTree.getObjectHitPos(pos1, pos2, out resultPos, modifyDist);
resultPos = convertPositionToInternalRep(resultPos.X, resultPos.Y, resultPos.Z);
rx = resultPos.X;
ry = resultPos.Y;
rz = resultPos.Z;
return result;
}
}
rx = x2;
ry = y2;
rz = z2;
return false;
}
@@ -175,6 +209,78 @@ namespace Game.Collision
return false;
}
public bool GetLiquidLevel(uint mapId, float x, float y, float z, byte reqLiquidType, ref float level, ref float floor, ref uint type)
{
if (!Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLiquidStatus))
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
LocationInfo info = new LocationInfo();
Vector3 pos = convertPositionToInternalRep(x, y, z);
if (instanceTree.GetLocationInfo(pos, info))
{
floor = info.ground_Z;
Contract.Assert(floor < float.MaxValue);
type = info.hitModel.GetLiquidType(); // entry from LiquidType.dbc
if (reqLiquidType != 0 && !Convert.ToBoolean(Global.DB2Mgr.GetLiquidFlags(type) & reqLiquidType))
return false;
if (info.hitInstance.GetLiquidLevel(pos, info, ref level))
return true;
}
}
}
return false;
}
public WorldModel acquireModelInstance(string filename)
{
var model = iLoadedModelFiles.LookupByKey(filename);
if (model == null)
{
WorldModel worldmodel = new WorldModel();
if (!worldmodel.readFile(VMapPath + filename + ".vmo"))
{
Log.outError(LogFilter.Server, "VMapManager: could not load '{0}.vmo'", filename);
return null;
}
Log.outDebug(LogFilter.Maps, "VMapManager: loading file '{0}'", filename);
iLoadedModelFiles.Add(filename, new ManagedModel());
model = iLoadedModelFiles.LookupByKey(filename);
model.setModel(worldmodel);
}
model.incRefCount();
return model.getModel();
}
public void releaseModelInstance(string filename)
{
var model = iLoadedModelFiles.LookupByKey(filename);
if (model == null)
{
Log.outError(LogFilter.Server, "VMapManager: trying to unload non-loaded file '{0}'", filename);
return;
}
if (model.decRefCount() == 0)
{
Log.outDebug(LogFilter.Maps, "VMapManager: unloading file '{0}'", filename);
iLoadedModelFiles.Remove(filename);
}
}
public bool existsMap(uint mapId, uint x, uint y)
{
return StaticMapTree.CanLoadMap(VMapPath, mapId, x, y, this);
}
public int getParentMapId(uint mapId)
{
if (iParentMapData.ContainsKey(mapId))
return (int)iParentMapData[mapId];
return -1;
}
Vector3 convertPositionToInternalRep(float x, float y, float z)
{
Vector3 pos = new Vector3();
@@ -186,6 +292,11 @@ namespace Game.Collision
return pos;
}
public static string getMapFileName(uint mapId)
{
return string.Format("{0:D4}.vmtree", mapId);
}
public void setEnableLineOfSightCalc(bool pVal) { _enableLineOfSightCalc = pVal; }
public void setEnableHeightCalc(bool pVal) { _enableHeightCalc = pVal; }
@@ -193,79 +304,10 @@ namespace Game.Collision
public bool isHeightCalcEnabled() { return _enableHeightCalc; }
public bool isMapLoadingEnabled() { return _enableLineOfSightCalc || _enableHeightCalc; }
public bool getObjectHitPos(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2, out float rx, out float ry, out float rz, float modifyDist)
{
if (isLineOfSightCalcEnabled() && !Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
Vector3 resultPos;
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
bool result = instanceTree.getObjectHitPos(pos1, pos2, out resultPos, modifyDist);
resultPos = convertPositionToInternalRep(resultPos.X, resultPos.Y, resultPos.Z);
rx = resultPos.X;
ry = resultPos.Y;
rz = resultPos.Z;
return result;
}
}
rx = x2;
ry = y2;
rz = z2;
return false;
}
public bool isInLineOfSight(uint mapId, float x1, float y1, float z1, float x2, float y2, float z2)
{
if (!isLineOfSightCalcEnabled() || Global.DisableMgr.IsDisabledFor(DisableType.VMAP, mapId, null, DisableFlags.VmapLOS))
return true;
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
Vector3 pos1 = convertPositionToInternalRep(x1, y1, z1);
Vector3 pos2 = convertPositionToInternalRep(x2, y2, z2);
if (pos1 != pos2)
{
return instanceTree.isInLineOfSight(pos1, pos2);
}
}
return true;
}
public void unloadMap(uint mapId)
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
instanceTree.UnloadMap(this);
if (instanceTree.numLoadedTiles() == 0)
{
iInstanceMapTrees.Remove(mapId);
}
}
}
public void unloadMap(uint mapId, uint x, uint y)
{
var instanceTree = iInstanceMapTrees.LookupByKey(mapId);
if (instanceTree != null)
{
instanceTree.UnloadMapTile(x, y, this);
if (instanceTree.numLoadedTiles() == 0)
{
iInstanceMapTrees.Remove(mapId);
}
}
}
Dictionary<string, ManagedModel> iLoadedModelFiles = new Dictionary<string, ManagedModel>();
Dictionary<uint, StaticMapTree> iInstanceMapTrees = new Dictionary<uint, StaticMapTree>();
MultiMap<uint, uint> iChildMapData = new MultiMap<uint, uint>();
Dictionary<uint, uint> iParentMapData = new Dictionary<uint, uint>();
bool _enableLineOfSightCalc;
bool _enableHeightCalc;
}
+93 -43
View File
@@ -64,6 +64,7 @@ namespace Game.Collision
bool success = false;
if (!File.Exists(fname))
return false;
char tiled = '0';
using (BinaryReader reader = new BinaryReader(new FileStream(fname, FileMode.Open, FileAccess.Read)))
{
@@ -99,6 +100,21 @@ namespace Game.Collision
Log.outError(LogFilter.Server, "StaticMapTree.InitMap() : could not acquire WorldModel for '{0}'", spawn.name);
}
}
if (success)
{
success = reader.ReadStringFromChars(4) == "SIDX";
if (success)
{
uint spawnIndicesSize = reader.ReadUInt32();
for (uint i = 0; i < spawnIndicesSize && success; ++i)
{
uint spawnId = reader.ReadUInt32();
uint spawnIndex = reader.ReadUInt32();
iSpawnIndices[spawnId] = spawnIndex;
}
}
}
}
return success;
}
@@ -131,15 +147,14 @@ namespace Game.Collision
}
bool result = true;
string tilefile = VMapManager.VMapPath + getTileFileName(iMapID, tileX, tileY);
if (!File.Exists(tilefile))
FileStream stream = OpenMapTileFile(VMapManager.VMapPath, iMapID, tileX, tileY, vm);
if (stream == null)
{
iLoadedTiles[packTileID(tileX, tileY)] = false;
}
else
{
using (BinaryReader reader = new BinaryReader(new FileStream(tilefile, FileMode.Open, FileAccess.Read)))
using (BinaryReader reader = new BinaryReader(stream))
{
if (reader.ReadStringFromChars(8) != MapConst.VMapMagic)
return false;
@@ -159,18 +174,27 @@ namespace Game.Collision
Log.outError(LogFilter.Server, "StaticMapTree.LoadMapTile() : could not acquire WorldModel [{0}, {1}]", tileX, tileY);
// update tree
uint referencedVal = reader.ReadUInt32();
if (!iLoadedSpawns.ContainsKey(referencedVal))
if (iSpawnIndices.ContainsKey(spawn.ID))
{
iTreeValues[referencedVal] = new ModelInstance(spawn, model);
iLoadedSpawns[referencedVal] = 1;
uint referencedVal = iSpawnIndices[spawn.ID];
if (!iLoadedSpawns.ContainsKey(referencedVal))
{
if (referencedVal >= iNTreeValues)
{
Log.outError(LogFilter.Maps, "StaticMapTree.LoadMapTile() : invalid tree element ({0}/{1}) referenced in tile {2}", referencedVal, iNTreeValues, stream.Name);
continue;
}
iTreeValues[referencedVal] = new ModelInstance(spawn, model);
iLoadedSpawns[referencedVal] = 1;
}
else
++iLoadedSpawns[referencedVal];
}
else
++iLoadedSpawns[referencedVal];
result = false;
}
else
result = false;
}
}
iLoadedTiles[packTileID(tileX, tileY)] = true;
@@ -189,36 +213,42 @@ namespace Game.Collision
}
if (tile) // file associated with tile
{
string tilefile = VMapManager.VMapPath + getTileFileName(iMapID, tileX, tileY);
using (BinaryReader reader = new BinaryReader(new FileStream(tilefile, FileMode.Open, FileAccess.Read)))
FileStream stream = OpenMapTileFile(VMapManager.VMapPath, iMapID, tileX, tileY, vm);
if (stream != null)
{
bool result = true;
if (reader.ReadStringFromChars(8) != MapConst.VMapMagic)
result = false;
uint numSpawns = reader.ReadUInt32();
for (uint i = 0; i < numSpawns && result; ++i)
using (BinaryReader reader = new BinaryReader(stream))
{
// read model spawns
ModelSpawn spawn;
result = ModelSpawn.readFromFile(reader, out spawn);
if (result)
bool result = true;
if (reader.ReadStringFromChars(8) != MapConst.VMapMagic)
result = false;
uint numSpawns = reader.ReadUInt32();
for (uint i = 0; i < numSpawns && result; ++i)
{
// release model instance
vm.releaseModelInstance(spawn.name);
// update tree
uint referencedNode = reader.ReadUInt32();
if (!iLoadedSpawns.ContainsKey(referencedNode))
Log.outError(LogFilter.Server, "StaticMapTree.UnloadMapTile() : trying to unload non-referenced model '{0}' (ID:{1})", spawn.name, spawn.ID);
else if (--iLoadedSpawns[referencedNode] == 0)
// read model spawns
ModelSpawn spawn;
result = ModelSpawn.readFromFile(reader, out spawn);
if (result)
{
iTreeValues[referencedNode].setUnloaded();
iLoadedSpawns.Remove(referencedNode);
}
// release model instance
vm.releaseModelInstance(spawn.name);
// update tree
if (!iSpawnIndices.ContainsKey(spawn.ID))
result = false;
else
{
uint referencedNode = iSpawnIndices[spawn.ID];
if (!iLoadedSpawns.ContainsKey(referencedNode))
Log.outError(LogFilter.Server, "StaticMapTree.UnloadMapTile() : trying to unload non-referenced model '{0}' (ID:{1})", spawn.name, spawn.ID);
else if (--iLoadedSpawns[referencedNode] == 0)
{
iTreeValues[referencedNode].setUnloaded();
iLoadedSpawns.Remove(referencedNode);
}
}
}
}
}
}
@@ -228,10 +258,26 @@ namespace Game.Collision
static uint packTileID(uint tileX, uint tileY) { return tileX << 16 | tileY; }
static void unpackTileID(uint ID, ref uint tileX, ref uint tileY) { tileX = ID >> 16; tileY = ID & 0xFF; }
public static bool CanLoadMap(string vmapPath, uint mapID, uint tileX, uint tileY)
static FileStream OpenMapTileFile(string vmapPath, uint mapID, uint tileX, uint tileY, VMapManager vm)
{
string tilefile = vmapPath + getTileFileName(mapID, tileX, tileY);
if (!File.Exists(tilefile))
{
int parentMapId = vm.getParentMapId(mapID);
if (parentMapId != -1)
tilefile = vmapPath + getTileFileName((uint)parentMapId, tileX, tileY);
}
if (!File.Exists(tilefile))
return null;
return new FileStream(tilefile, FileMode.Open, FileAccess.Read);
}
public static bool CanLoadMap(string vmapPath, uint mapID, uint tileX, uint tileY, VMapManager vm)
{
string fullname = vmapPath + VMapManager.getMapFileName(mapID);
bool success = true;
if (!File.Exists(fullname))
return false;
@@ -239,21 +285,24 @@ namespace Game.Collision
{
if (reader.ReadStringFromChars(8) != MapConst.VMapMagic)
return false;
char tiled = reader.ReadChar();
if (tiled == 1)
{
string tilefile = vmapPath + getTileFileName(mapID, tileX, tileY);
if (!File.Exists(tilefile))
FileStream stream = OpenMapTileFile(vmapPath, mapID, tileX, tileY, vm);
if (stream == null)
return false;
using (BinaryReader reader1 = new BinaryReader(new FileStream(tilefile, FileMode.Open, FileAccess.Read)))
using (BinaryReader reader1 = new BinaryReader(stream))
{
if (reader1.ReadStringFromChars(8) != MapConst.VMapMagic)
success = false;
return false;
}
}
}
return success;
return true;
}
public static string getTileFileName(uint mapID, uint tileX, uint tileY)
{
@@ -380,6 +429,7 @@ namespace Game.Collision
BIH iTree = new BIH();
ModelInstance[] iTreeValues;
uint iNTreeValues;
Dictionary<uint, uint> iSpawnIndices = new Dictionary<uint, uint>();
Dictionary<uint, bool> iLoadedTiles = new Dictionary<uint, bool>();
Dictionary<uint, uint> iLoadedSpawns = new Dictionary<uint, uint>();
@@ -31,7 +31,7 @@ namespace Game.Collision
{
public virtual bool IsSpawned() { return false; }
public virtual uint GetDisplayId() { return 0; }
public virtual bool IsInPhase(List<uint> phases) { return false; }
public virtual bool IsInPhase(PhaseShift phaseShift) { return false; }
public virtual Vector3 GetPosition() { return Vector3.Zero; }
public virtual float GetOrientation() { return 0.0f; }
public virtual float GetScale() { return 1.0f; }
@@ -86,12 +86,12 @@ namespace Game.Collision
return mdl;
}
public override bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, List<uint> phases)
public override bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, PhaseShift phaseShift)
{
if (!isCollisionEnabled() || !owner.IsSpawned())
return false;
if (!owner.IsInPhase(phases))
if (!owner.IsInPhase(phaseShift))
return false;
float time = ray.intersectionTime(iBound);
+1 -1
View File
@@ -25,7 +25,7 @@ namespace Game.Collision
public virtual Vector3 getPosition() { return default(Vector3); }
public virtual AxisAlignedBox getBounds() { return default(AxisAlignedBox); }
public virtual bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, List<uint> phases) { return false; }
public virtual bool IntersectRay(Ray ray, ref float maxDist, bool stopAtFirstHit, PhaseShift phaseShift) { return false; }
public virtual bool IntersectRay(Ray ray, ref float distance, bool stopAtFirstHit) { return false; }
}
}