Merge branch 'master' of /home/opensim/var/repo/opensim
commit
09dc8d6f96
|
@ -307,7 +307,7 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
}
|
}
|
||||||
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
|
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
|
||||||
{
|
{
|
||||||
float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position);
|
float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
|
||||||
if (Position.Z < waterHeight)
|
if (Position.Z < waterHeight)
|
||||||
{
|
{
|
||||||
_position.Z = waterHeight;
|
_position.Z = waterHeight;
|
||||||
|
|
|
@ -445,9 +445,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY
|
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY
|
||||||
| VehicleFlag.HOVER_GLOBAL_HEIGHT
|
| VehicleFlag.HOVER_GLOBAL_HEIGHT
|
||||||
| VehicleFlag.LIMIT_ROLL_ONLY
|
| VehicleFlag.LIMIT_ROLL_ONLY
|
||||||
|
| VehicleFlag.LIMIT_MOTOR_UP
|
||||||
| VehicleFlag.HOVER_UP_ONLY);
|
| VehicleFlag.HOVER_UP_ONLY);
|
||||||
m_flags |= (VehicleFlag.NO_DEFLECTION_UP
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP
|
||||||
| VehicleFlag.LIMIT_MOTOR_UP
|
|
||||||
| VehicleFlag.HOVER_WATER_ONLY);
|
| VehicleFlag.HOVER_WATER_ONLY);
|
||||||
break;
|
break;
|
||||||
case Vehicle.TYPE_AIRPLANE:
|
case Vehicle.TYPE_AIRPLANE:
|
||||||
|
@ -713,7 +713,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// We should hover, get the target height
|
// We should hover, get the target height
|
||||||
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||||
{
|
{
|
||||||
m_VhoverTargetHeight = Prim.PhysicsScene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
|
m_VhoverTargetHeight = Prim.PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
|
||||||
}
|
}
|
||||||
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||||
{
|
{
|
||||||
|
@ -730,6 +730,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if (pos.Z > m_VhoverTargetHeight)
|
if (pos.Z > m_VhoverTargetHeight)
|
||||||
m_VhoverTargetHeight = pos.Z;
|
m_VhoverTargetHeight = pos.Z;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||||
{
|
{
|
||||||
if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f)
|
if (Math.Abs(pos.Z - m_VhoverTargetHeight) > 0.2f)
|
||||||
|
@ -804,6 +805,13 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// From http://wiki.secondlife.com/wiki/LlSetVehicleFlags :
|
||||||
|
// Prevent ground vehicles from motoring into the sky.This flag has a subtle effect when
|
||||||
|
// used with conjunction with banking: the strength of the banking will decay when the
|
||||||
|
// vehicle no longer experiences collisions. The decay timescale is the same as
|
||||||
|
// VEHICLE_BANKING_TIMESCALE. This is to help prevent ground vehicles from steering
|
||||||
|
// when they are in mid jump.
|
||||||
|
// TODO: this code is wrong. Also, what should it do for boats?
|
||||||
public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight)
|
public Vector3 ComputeLinearMotorUp(float pTimestep, Vector3 pos, float terrainHeight)
|
||||||
{
|
{
|
||||||
Vector3 ret = Vector3.Zero;
|
Vector3 ret = Vector3.Zero;
|
||||||
|
@ -817,10 +825,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
// downForce = new Vector3(0, 0, -distanceAboveGround / m_bankingTimescale);
|
||||||
ret = new Vector3(0, 0, -distanceAboveGround);
|
ret = new Vector3(0, 0, -distanceAboveGround);
|
||||||
}
|
}
|
||||||
// TODO: this calculation is all wrong. From the description at
|
// TODO: this calculation is wrong. From the description at
|
||||||
// (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
|
// (http://wiki.secondlife.com/wiki/Category:LSL_Vehicle), the downForce
|
||||||
// has a decay factor. This says this force should
|
// has a decay factor. This says this force should
|
||||||
// be computed with a motor.
|
// be computed with a motor.
|
||||||
|
// TODO: add interaction with banking.
|
||||||
VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}",
|
VDetailLog("{0},MoveLinear,limitMotorUp,distAbove={1},downForce={2}",
|
||||||
Prim.LocalID, distanceAboveGround, ret);
|
Prim.LocalID, distanceAboveGround, ret);
|
||||||
}
|
}
|
||||||
|
@ -863,7 +872,11 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep);
|
Vector3 angularMotorContribution = m_angularMotor.Step(pTimestep);
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
// NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
|
// From http://wiki.secondlife.com/wiki/LlSetVehicleFlags :
|
||||||
|
// This flag prevents linear deflection parallel to world z-axis. This is useful
|
||||||
|
// for preventing ground vehicles with large linear deflection, like bumper cars,
|
||||||
|
// from climbing their linear deflection into the sky.
|
||||||
|
// That is, NO_DEFLECTION_UP says angular motion should not add any pitch or roll movement
|
||||||
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
|
||||||
{
|
{
|
||||||
angularMotorContribution.X = 0f;
|
angularMotorContribution.X = 0f;
|
||||||
|
@ -883,8 +896,8 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
// Sum velocities
|
// Sum velocities
|
||||||
m_lastAngularVelocity = angularMotorContribution
|
m_lastAngularVelocity = angularMotorContribution
|
||||||
+ verticalAttractionContribution
|
+ verticalAttractionContribution
|
||||||
+ bankingContribution
|
+ deflectionContribution
|
||||||
+ deflectionContribution;
|
+ bankingContribution;
|
||||||
|
|
||||||
// ==================================================================
|
// ==================================================================
|
||||||
//Offset section
|
//Offset section
|
||||||
|
@ -921,8 +934,9 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
||||||
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
if (m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
{
|
{
|
||||||
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
||||||
Prim.ZeroAngularMotion(true);
|
// TODO: zeroing is good but it also sets values in unmanaged code. Remove the stores when idle.
|
||||||
VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
|
VDetailLog("{0},MoveAngular,zeroAngularMotion,lastAngular={1}", Prim.LocalID, m_lastAngularVelocity);
|
||||||
|
Prim.ZeroAngularMotion(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -253,8 +253,9 @@ public sealed class BSPrim : BSPhysObject
|
||||||
// Zero some other properties in the physics engine
|
// Zero some other properties in the physics engine
|
||||||
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
|
PhysicsScene.TaintedObject(inTaintTime, "BSPrim.ZeroMotion", delegate()
|
||||||
{
|
{
|
||||||
BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
|
// DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
|
||||||
BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, OMV.Vector3.Zero);
|
BulletSimAPI.SetInterpolationAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
|
||||||
|
BulletSimAPI.SetAngularVelocity2(PhysBody.ptr, _rotationalVelocity);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +330,7 @@ public sealed class BSPrim : BSPhysObject
|
||||||
|
|
||||||
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
|
if ((CurrentCollisionFlags & CollisionFlags.BS_FLOATS_ON_WATER) != 0)
|
||||||
{
|
{
|
||||||
float waterHeight = PhysicsScene.GetWaterLevelAtXYZ(_position);
|
float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(_position);
|
||||||
// TODO: a floating motor so object will bob in the water
|
// TODO: a floating motor so object will bob in the water
|
||||||
if (Math.Abs(Position.Z - waterHeight) > 0.1f)
|
if (Math.Abs(Position.Z - waterHeight) > 0.1f)
|
||||||
{
|
{
|
||||||
|
|
|
@ -127,7 +127,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
public const uint GROUNDPLANE_ID = 1;
|
public const uint GROUNDPLANE_ID = 1;
|
||||||
public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
|
public const uint CHILDTERRAIN_ID = 2; // Terrain allocated based on our mega-prim childre start here
|
||||||
|
|
||||||
private float m_waterLevel;
|
public float SimpleWaterLevel { get; set; }
|
||||||
public BSTerrainManager TerrainManager { get; private set; }
|
public BSTerrainManager TerrainManager { get; private set; }
|
||||||
|
|
||||||
public ConfigurationParameters Params
|
public ConfigurationParameters Params
|
||||||
|
@ -182,6 +182,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
private string m_physicsLoggingDir;
|
private string m_physicsLoggingDir;
|
||||||
private string m_physicsLoggingPrefix;
|
private string m_physicsLoggingPrefix;
|
||||||
private int m_physicsLoggingFileMinutes;
|
private int m_physicsLoggingFileMinutes;
|
||||||
|
private bool m_physicsLoggingDoFlush;
|
||||||
// 'true' of the vehicle code is to log lots of details
|
// 'true' of the vehicle code is to log lots of details
|
||||||
public bool VehicleLoggingEnabled { get; private set; }
|
public bool VehicleLoggingEnabled { get; private set; }
|
||||||
|
|
||||||
|
@ -290,6 +291,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
|
m_physicsLoggingDir = pConfig.GetString("PhysicsLoggingDir", ".");
|
||||||
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
|
m_physicsLoggingPrefix = pConfig.GetString("PhysicsLoggingPrefix", "physics-%REGIONNAME%-");
|
||||||
m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
|
m_physicsLoggingFileMinutes = pConfig.GetInt("PhysicsLoggingFileMinutes", 5);
|
||||||
|
m_physicsLoggingDoFlush = pConfig.GetBoolean("PhysicsLoggingDoFlush", false);
|
||||||
// Very detailed logging for vehicle debugging
|
// Very detailed logging for vehicle debugging
|
||||||
VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
|
VehicleLoggingEnabled = pConfig.GetBoolean("VehicleLoggingEnabled", false);
|
||||||
|
|
||||||
|
@ -494,7 +496,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG
|
// if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG
|
||||||
if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
|
if (PhysicsLogging.Enabled) beforeTime = Util.EnvironmentTickCount();
|
||||||
|
|
||||||
numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
numSubSteps = BulletSimAPI.PhysicsStep2(World.ptr, timeStep, m_maxSubSteps, m_fixedTimeStep,
|
||||||
|
@ -503,7 +505,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
|
if (PhysicsLogging.Enabled) simTime = Util.EnvironmentTickCountSubtract(beforeTime);
|
||||||
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
|
DetailLog("{0},Simulate,call, frame={1}, nTaints={2}, simTime={3}, substeps={4}, updates={5}, colliders={6}",
|
||||||
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
|
DetailLogZero, m_simulationStep, numTaints, simTime, numSubSteps, updatedEntityCount, collidersCount);
|
||||||
if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG
|
// if (VehicleLoggingEnabled) DumpVehicles(); // DEBUG
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -634,12 +636,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
|
|
||||||
public override void SetWaterLevel(float baseheight)
|
public override void SetWaterLevel(float baseheight)
|
||||||
{
|
{
|
||||||
m_waterLevel = baseheight;
|
SimpleWaterLevel = baseheight;
|
||||||
}
|
|
||||||
// Someday....
|
|
||||||
public float GetWaterLevelAtXYZ(Vector3 loc)
|
|
||||||
{
|
|
||||||
return m_waterLevel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DeleteTerrain()
|
public override void DeleteTerrain()
|
||||||
|
@ -1493,7 +1490,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
{
|
{
|
||||||
PhysicsLogging.Write(msg, args);
|
PhysicsLogging.Write(msg, args);
|
||||||
// Add the Flush() if debugging crashes. Gets all the messages written out.
|
// Add the Flush() if debugging crashes. Gets all the messages written out.
|
||||||
// PhysicsLogging.Flush();
|
if (m_physicsLoggingDoFlush) PhysicsLogging.Flush();
|
||||||
}
|
}
|
||||||
// Used to fill in the LocalID when there isn't one. It's the correct number of characters.
|
// Used to fill in the LocalID when there isn't one. It's the correct number of characters.
|
||||||
public const string DetailLogZero = "0000000000";
|
public const string DetailLogZero = "0000000000";
|
||||||
|
|
|
@ -148,7 +148,7 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
||||||
}
|
}
|
||||||
|
|
||||||
// The passed position is relative to the base of the region.
|
// The passed position is relative to the base of the region.
|
||||||
public override float GetHeightAtXYZ(Vector3 pos)
|
public override float GetTerrainHeightAtXYZ(Vector3 pos)
|
||||||
{
|
{
|
||||||
float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
|
float ret = BSTerrainManager.HEIGHT_GETHEIGHT_RET;
|
||||||
|
|
||||||
|
@ -166,5 +166,11 @@ public sealed class BSTerrainHeightmap : BSTerrainPhys
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The passed position is relative to the base of the region.
|
||||||
|
public override float GetWaterLevelAtXYZ(Vector3 pos)
|
||||||
|
{
|
||||||
|
return PhysicsScene.SimpleWaterLevel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,8 @@ public abstract class BSTerrainPhys : IDisposable
|
||||||
ID = id;
|
ID = id;
|
||||||
}
|
}
|
||||||
public abstract void Dispose();
|
public abstract void Dispose();
|
||||||
public abstract float GetHeightAtXYZ(Vector3 pos);
|
public abstract float GetTerrainHeightAtXYZ(Vector3 pos);
|
||||||
|
public abstract float GetWaterLevelAtXYZ(Vector3 pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==========================================================================================
|
// ==========================================================================================
|
||||||
|
@ -75,6 +76,7 @@ public sealed class BSTerrainManager
|
||||||
public const float HEIGHT_INITIALIZATION = 24.987f;
|
public const float HEIGHT_INITIALIZATION = 24.987f;
|
||||||
public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f;
|
public const float HEIGHT_INITIAL_LASTHEIGHT = 24.876f;
|
||||||
public const float HEIGHT_GETHEIGHT_RET = 24.765f;
|
public const float HEIGHT_GETHEIGHT_RET = 24.765f;
|
||||||
|
public const float WATER_HEIGHT_GETHEIGHT_RET = 19.998f;
|
||||||
|
|
||||||
// If the min and max height are equal, we reduce the min by this
|
// If the min and max height are equal, we reduce the min by this
|
||||||
// amount to make sure that a bounding box is built for the terrain.
|
// amount to make sure that a bounding box is built for the terrain.
|
||||||
|
@ -358,7 +360,7 @@ public sealed class BSTerrainManager
|
||||||
BSTerrainPhys physTerrain;
|
BSTerrainPhys physTerrain;
|
||||||
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
||||||
{
|
{
|
||||||
ret = physTerrain.GetHeightAtXYZ(loc - terrainBaseXYZ);
|
ret = physTerrain.GetTerrainHeightAtXYZ(loc - terrainBaseXYZ);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -370,6 +372,33 @@ public sealed class BSTerrainManager
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float GetWaterLevelAtXYZ(Vector3 pos)
|
||||||
|
{
|
||||||
|
float ret = WATER_HEIGHT_GETHEIGHT_RET;
|
||||||
|
|
||||||
|
float tX = pos.X;
|
||||||
|
float tY = pos.Y;
|
||||||
|
|
||||||
|
Vector3 terrainBaseXYZ = Vector3.Zero;
|
||||||
|
terrainBaseXYZ.X = ((int)(tX / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
|
||||||
|
terrainBaseXYZ.Y = ((int)(tY / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
|
||||||
|
|
||||||
|
lock (m_terrains)
|
||||||
|
{
|
||||||
|
BSTerrainPhys physTerrain;
|
||||||
|
if (m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain))
|
||||||
|
{
|
||||||
|
ret = physTerrain.GetWaterLevelAtXYZ(pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhysicsScene.Logger.ErrorFormat("{0} GetWaterHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||||
|
LogHeader, PhysicsScene.RegionName, tX, tY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Although no one seems to check this, I do support combining.
|
// Although no one seems to check this, I do support combining.
|
||||||
public bool SupportsCombining()
|
public bool SupportsCombining()
|
||||||
{
|
{
|
||||||
|
|
|
@ -148,7 +148,7 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetHeightAtXYZ(Vector3 pos)
|
public override float GetTerrainHeightAtXYZ(Vector3 pos)
|
||||||
{
|
{
|
||||||
// For the moment use the saved heightmap to get the terrain height.
|
// For the moment use the saved heightmap to get the terrain height.
|
||||||
// TODO: raycast downward to find the true terrain below the position.
|
// TODO: raycast downward to find the true terrain below the position.
|
||||||
|
@ -169,6 +169,12 @@ public sealed class BSTerrainMesh : BSTerrainPhys
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The passed position is relative to the base of the region.
|
||||||
|
public override float GetWaterLevelAtXYZ(Vector3 pos)
|
||||||
|
{
|
||||||
|
return PhysicsScene.SimpleWaterLevel;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert the passed heightmap to mesh information suitable for CreateMeshShape2().
|
// Convert the passed heightmap to mesh information suitable for CreateMeshShape2().
|
||||||
// Return 'true' if successfully created.
|
// Return 'true' if successfully created.
|
||||||
public static bool ConvertHeightmapToMesh(
|
public static bool ConvertHeightmapToMesh(
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue