Added RigidBody::ReAddBodyToWorld().

Added heightfield smoothing attribute.
Allow CollisionShape::SetTriangleMesh() & SetConvexHull() without specifying LOD level (0 is default)
Refactored Vehicle example and increased vehicle speed.
This commit is contained in:
Lasse Öörni 2013-06-12 21:09:36 +00:00
parent 633378312b
commit 27b31af0cf
14 changed files with 147 additions and 94 deletions

View File

@ -177,7 +177,7 @@ void InitScene()
RigidBody@ body = objectNode.CreateComponent("RigidBody");
CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
shape.SetTriangleMesh(object.model, 0);
shape.SetTriangleMesh(object.model);
}
testScene.CreateComponent("Navigable");
@ -424,7 +424,7 @@ void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
RigidBody@ body = objectNode.CreateComponent("RigidBody");
CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
shape.SetTriangleMesh(object.model, 0);
shape.SetTriangleMesh(object.model);
rebuild = true;
rebuildBox = object.worldBoundingBox;

View File

@ -173,7 +173,7 @@ void InitScene()
RigidBody@ body = objectNode.CreateComponent("RigidBody");
CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"), 0);
shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"));
}
}

View File

@ -135,6 +135,7 @@ void InitScene()
terrain = terrainNode.CreateComponent("Terrain");
terrain.patchSize = 64;
terrain.spacing = Vector3(2, 0.5, 2);
terrain.smoothing = true;
terrain.heightMap = cache.GetResource("Image", "Textures/HeightMap.png");
terrain.material = cache.GetResource("Material", "Materials/Terrain.xml");
terrain.occluder = true;
@ -162,7 +163,7 @@ void InitScene()
RigidBody@ body = objectNode.CreateComponent("RigidBody");
CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"), 0);
shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"));
}
}

View File

@ -186,7 +186,7 @@ void InitScene()
RigidBody@ body = objectNode.CreateComponent("RigidBody");
CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
shape.SetTriangleMesh(object.model, 0);
shape.SetTriangleMesh(object.model);
}
for (uint i = 0; i < 50; ++i)

View File

@ -126,7 +126,7 @@ void InitScene()
RigidBody@ body = newNode.CreateComponent("RigidBody");
CollisionShape@ shape = newNode.CreateComponent("CollisionShape");
shape.SetTriangleMesh(object.model, 0);
shape.SetTriangleMesh(object.model);
}
// Create mushroom groups

View File

@ -1,7 +1,7 @@
Scene@ testScene;
Camera@ camera;
Node@ cameraNode;
Node@ vehicleHullNode;
Node@ vehicleNode;
float yaw = 0.0;
float pitch = 0.0;
@ -18,7 +18,6 @@ void Start()
OpenConsoleWindow();
InitScene();
InitVehicle();
SubscribeToEvent("Update", "HandleUpdate");
SubscribeToEvent("PostUpdate", "HandlePostUpdate");
@ -103,6 +102,7 @@ void InitScene()
terrain = terrainNode.CreateComponent("Terrain");
terrain.patchSize = 64;
terrain.spacing = Vector3(2, 0.1, 2);
terrain.smoothing = true;
terrain.heightMap = cache.GetResource("Image", "Textures/HeightMap.png");
terrain.material = cache.GetResource("Material", "Materials/Terrain.xml");
terrain.occluder = true;
@ -111,7 +111,6 @@ void InitScene()
body.collisionLayer = 2;
CollisionShape@ shape = terrainNode.CreateComponent("CollisionShape");
shape.SetTerrain();
shape.margin = 0.01;
}
for (uint i = 0; i < 1000; ++i)
@ -132,8 +131,14 @@ void InitScene()
RigidBody@ body = objectNode.CreateComponent("RigidBody");
body.collisionLayer = 2;
CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"), 0);
shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"));
}
vehicleNode = testScene.CreateChild("VehicleHull");
vehicleNode.position = Vector3(0, 5, 0);
Vehicle@ vehicle = cast<Vehicle>(vehicleNode.CreateScriptObject(scriptFile, "Vehicle"));
vehicle.Init();
}
void HandleUpdate(StringHash eventType, VariantMap& eventData)
@ -148,12 +153,12 @@ void HandlePostUpdate(StringHash eventType, VariantMap& eventData)
float timeStep = eventData["TimeStep"].GetFloat();
// Physics update has completed. Position camera behind vehicle
Quaternion dir(vehicleHullNode.rotation.yaw, Vector3(0, 1, 0));;
Quaternion dir(vehicleNode.rotation.yaw, Vector3(0, 1, 0));;
dir = dir * Quaternion(yaw, Vector3(0, 1, 0));
dir = dir * Quaternion(pitch, Vector3(1, 0, 0));
Vector3 cameraTargetPos = vehicleHullNode.position - dir * Vector3(0, 0, 10);
Vector3 cameraStartPos = vehicleHullNode.position;
Vector3 cameraTargetPos = vehicleNode.position - dir * Vector3(0, 0, 10);
Vector3 cameraStartPos = vehicleNode.position;
// Raycast camera against static objects (physics collision mask 2)
// and move it closer to the vehicle if something in between
@ -266,66 +271,6 @@ void HandlePostRenderUpdate()
testScene.physicsWorld.DrawDebugGeometry(true);
}
void InitVehicle()
{
vehicleHullNode = testScene.CreateChild("VehicleHull");
StaticModel@ hullObject = vehicleHullNode.CreateComponent("StaticModel");
RigidBody@ hullBody = vehicleHullNode.CreateComponent("RigidBody");
CollisionShape@ hullShape = vehicleHullNode.CreateComponent("CollisionShape");
vehicleHullNode.position = Vector3(0, 5, 0);
vehicleHullNode.scale = Vector3(1.5, 1, 3);
hullObject.model = cache.GetResource("Model", "Models/Box.mdl");
hullObject.material = cache.GetResource("Material", "Materials/Stone.xml");
hullObject.castShadows = true;
hullShape.SetBox(Vector3(1, 1, 1));
hullBody.mass = 3;
hullBody.linearDamping = 0.2; // Some air resistance
hullBody.collisionLayer = 1;
Node@ fl = InitVehicleWheel("FrontLeft", vehicleHullNode, Vector3(-0.6, -0.4, 0.3));
Node@ fr = InitVehicleWheel("FrontRight", vehicleHullNode, Vector3(0.6, -0.4, 0.3));
Node@ rr = InitVehicleWheel("RearLeft", vehicleHullNode, Vector3(-0.6, -0.4, -0.3));
Node@ rl = InitVehicleWheel("RearRight", vehicleHullNode, Vector3(0.6, -0.4, -0.3));
Vehicle@ vehicle = cast<Vehicle>(vehicleHullNode.CreateScriptObject(scriptFile, "Vehicle"));
vehicle.SetWheels(fl, fr, rl, rr);
}
Node@ InitVehicleWheel(String name, Node@ vehicleHullNode, Vector3 offset)
{
Node@ wheelNode = testScene.CreateChild(name);
wheelNode.position = vehicleHullNode.LocalToWorld(offset);
wheelNode.rotation = vehicleHullNode.worldRotation * (offset.x >= 0.0 ? Quaternion(0, 0, -90) : Quaternion(0, 0, 90));
wheelNode.scale = Vector3(0.75, 0.5, 0.75);
StaticModel@ wheelObject = wheelNode.CreateComponent("StaticModel");
RigidBody@ wheelBody = wheelNode.CreateComponent("RigidBody");
CollisionShape@ wheelShape = wheelNode.CreateComponent("CollisionShape");
Constraint@ wheelConstraint = wheelNode.CreateComponent("Constraint");
wheelObject.model = cache.GetResource("Model", "Models/Cylinder.mdl");
wheelObject.material = cache.GetResource("Material", "Materials/Stone.xml");
wheelObject.castShadows = true;
wheelShape.SetCylinder(1, 1);
wheelBody.friction = 1;
wheelBody.mass = 1;
wheelBody.linearDamping = 0.2; // Some air resistance
wheelBody.angularDamping = 0.75; // Current version of Bullet used by Urho doesn't have rolling friction, so mimic that with
// some angular damping on the wheels
wheelBody.collisionLayer = 1;
wheelConstraint.constraintType = CONSTRAINT_HINGE;
wheelConstraint.otherBody = vehicleHullNode.GetComponent("RigidBody");
wheelConstraint.worldPosition = wheelNode.worldPosition; // Set constraint's both ends at wheel's location
wheelConstraint.axis = Vector3(0, 1, 0); // Wheel rotates around its local Y-axis
wheelConstraint.otherAxis = offset.x >= 0.0 ? Vector3(1, 0, 0) : Vector3(-1, 0, 0); // Wheel's hull axis points either left or right
wheelConstraint.lowLimit = Vector2(-180, 0); // Let the wheel rotate freely around the axis
wheelConstraint.highLimit = Vector2(180, 0);
wheelConstraint.disableCollision = true; // Let the wheel intersect the vehicle hull
return wheelNode;
}
class Vehicle : ScriptObject
{
Node@ frontLeft;
@ -341,18 +286,31 @@ class Vehicle : ScriptObject
RigidBody@ rearRightBody;
float steering = 0.0;
float enginePower = 8.0;
float enginePower = 10.0;
float downForce = 10.0;
float maxWheelAngle = 22.5;
void SetWheels(Node@ fl, Node@ fr, Node@ rl, Node@ rr)
void Init()
{
frontLeft = fl;
frontRight = fr;
rearLeft = rl;
rearRight = rr;
StaticModel@ hullObject = node.CreateComponent("StaticModel");
hullBody = node.CreateComponent("RigidBody");
CollisionShape@ hullShape = node.CreateComponent("CollisionShape");
hullBody = node.GetComponent("RigidBody");
node.scale = Vector3(1.5, 1, 3);
hullObject.model = cache.GetResource("Model", "Models/Box.mdl");
hullObject.material = cache.GetResource("Material", "Materials/Stone.xml");
hullObject.castShadows = true;
hullShape.SetBox(Vector3(1, 1, 1));
hullBody.mass = 4;
hullBody.linearDamping = 0.2; // Some air resistance
hullBody.angularDamping = 0.5;
hullBody.collisionLayer = 1;
frontLeft = InitWheel("FrontLeft", Vector3(-0.6, -0.4, 0.3));
frontRight = InitWheel("FrontRight", Vector3(0.6, -0.4, 0.3));
rearLeft = InitWheel("RearLeft", Vector3(-0.6, -0.4, -0.3));
rearRight = InitWheel("RearRight", Vector3(0.6, -0.4, -0.3));
frontLeftAxis = frontLeft.GetComponent("Constraint");
frontRightAxis = frontRight.GetComponent("Constraint");
frontLeftBody = frontLeft.GetComponent("RigidBody");
@ -361,6 +319,40 @@ class Vehicle : ScriptObject
rearRightBody = rearRight.GetComponent("RigidBody");
}
Node@ InitWheel(const String&in name, const Vector3&in offset)
{
Node@ wheelNode = testScene.CreateChild(name);
wheelNode.position = node.LocalToWorld(offset);
wheelNode.rotation = node.worldRotation * (offset.x >= 0.0 ? Quaternion(0, 0, -90) : Quaternion(0, 0, 90));
wheelNode.scale = Vector3(0.8, 0.5, 0.8);
StaticModel@ wheelObject = wheelNode.CreateComponent("StaticModel");
RigidBody@ wheelBody = wheelNode.CreateComponent("RigidBody");
CollisionShape@ wheelShape = wheelNode.CreateComponent("CollisionShape");
Constraint@ wheelConstraint = wheelNode.CreateComponent("Constraint");
wheelObject.model = cache.GetResource("Model", "Models/Cylinder.mdl");
wheelObject.material = cache.GetResource("Material", "Materials/Stone.xml");
wheelObject.castShadows = true;
wheelShape.SetSphere(1);
wheelBody.friction = 1;
wheelBody.mass = 1;
wheelBody.linearDamping = 0.2; // Some air resistance
wheelBody.angularDamping = 0.75; // Current version of Bullet used by Urho doesn't have rolling friction, so mimic that with
// some angular damping on the wheels
wheelBody.collisionLayer = 1;
wheelConstraint.constraintType = CONSTRAINT_HINGE;
wheelConstraint.otherBody = node.GetComponent("RigidBody");
wheelConstraint.worldPosition = wheelNode.worldPosition; // Set constraint's both ends at wheel's location
wheelConstraint.axis = Vector3(0, 1, 0); // Wheel rotates around its local Y-axis
wheelConstraint.otherAxis = offset.x >= 0.0 ? Vector3(1, 0, 0) : Vector3(-1, 0, 0); // Wheel's hull axis points either left or right
wheelConstraint.lowLimit = Vector2(-180, 0); // Let the wheel rotate freely around the axis
wheelConstraint.highLimit = Vector2(180, 0);
wheelConstraint.disableCollision = true; // Let the wheel intersect the vehicle hull
return wheelNode;
}
void FixedUpdate(float timeStep)
{
float newSteering = 0.0;
@ -405,7 +397,7 @@ class Vehicle : ScriptObject
}
// Apply downforce proportional to velocity
Vector3 localVelocity = node.worldRotation.Inverse() * hullBody.linearVelocity;
hullBody.ApplyForce(node.worldRotation * Vector3(0, -1, 0) * Abs(localVelocity.z) * downForce);
Vector3 localVelocity = hullBody.rotation.Inverse() * hullBody.linearVelocity;
hullBody.ApplyForce(hullBody.rotation * Vector3(0, -1, 0) * Abs(localVelocity.z) * downForce);
}
}

View File

@ -2937,6 +2937,7 @@ Properties:<br>
- uint id (readonly)
- Node@ node (readonly)
- Material@ material
- bool smoothing
- Image@ heightMap
- int patchSize
- Vector3 spacing
@ -5653,8 +5654,8 @@ Methods:<br>
- void SetCylinder(float, float, const Vector3& arg2 = Vector3 ( ), const Quaternion& arg3 = Quaternion ( ))
- void SetCapsule(float, float, const Vector3& arg2 = Vector3 ( ), const Quaternion& arg3 = Quaternion ( ))
- void SetCone(float, float, const Vector3& arg2 = Vector3 ( ), const Quaternion& arg3 = Quaternion ( ))
- void SetTriangleMesh(Model@, uint, const Vector3& arg2 = Vector3 ( 1 , 1 , 1 ), const Vector3& arg3 = Vector3 ( ), const Quaternion& arg4 = Quaternion ( ))
- void SetConvexHull(Model@, uint, const Vector3& arg2 = Vector3 ( 1 , 1 , 1 ), const Vector3& arg3 = Vector3 ( ), const Quaternion& arg4 = Quaternion ( ))
- void SetTriangleMesh(Model@, uint arg1 = 0, const Vector3& arg2 = Vector3 ( 1 , 1 , 1 ), const Vector3& arg3 = Vector3 ( ), const Quaternion& arg4 = Quaternion ( ))
- void SetConvexHull(Model@, uint arg1 = 0, const Vector3& arg2 = Vector3 ( 1 , 1 , 1 ), const Vector3& arg3 = Vector3 ( ), const Quaternion& arg4 = Quaternion ( ))
- void SetCustomConvexHull(CustomGeometry@, const Vector3& arg1 = Vector3 ( 1 , 1 , 1 ), const Vector3& arg2 = Vector3 ( ), const Quaternion& arg3 = Quaternion ( ))
- void SetTerrain()
- void SetTransform(const Vector3&, const Quaternion&)
@ -5710,6 +5711,7 @@ Methods:<br>
- void ApplyTorqueImpulse(const Vector3&)
- void ResetForces()
- void Activate()
- void ReAddBodyToWorld()
- Vector3 GetVelocityAtPoint(const Vector3&) const
Properties:<br>

View File

@ -1034,6 +1034,8 @@ static void RegisterTerrain(asIScriptEngine* engine)
engine->RegisterObjectMethod("Terrain", "TerrainPatch@+ GetPatch(int, int) const", asMETHODPR(Terrain, GetPatch, (int, int) const, TerrainPatch*), asCALL_THISCALL);
engine->RegisterObjectMethod("Terrain", "void set_material(Material@+)", asMETHOD(Terrain, SetMaterial), asCALL_THISCALL);
engine->RegisterObjectMethod("Terrain", "Material@+ get_material() const", asMETHOD(Terrain, GetMaterial), asCALL_THISCALL);
engine->RegisterObjectMethod("Terrain", "void set_smoothing(bool)", asMETHOD(Terrain, SetSmoothing), asCALL_THISCALL);
engine->RegisterObjectMethod("Terrain", "bool get_smoothing() const", asMETHOD(Terrain, GetSmoothing), asCALL_THISCALL);
engine->RegisterObjectMethod("Terrain", "void set_heightMap(Image@+)", asMETHOD(Terrain, SetHeightMap), asCALL_THISCALL);
engine->RegisterObjectMethod("Terrain", "Image@+ get_heightMap() const", asMETHOD(Terrain, GetHeightMap), asCALL_THISCALL);
engine->RegisterObjectMethod("Terrain", "void set_patchSize(int)", asMETHOD(Terrain, SetPatchSize), asCALL_THISCALL);

View File

@ -77,8 +77,8 @@ static void RegisterCollisionShape(asIScriptEngine* engine)
engine->RegisterObjectMethod("CollisionShape", "void SetCylinder(float, float, const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetCylinder), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetCapsule(float, float, const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetCapsule), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetCone(float, float, const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetCone), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetTriangleMesh(Model@+, uint, const Vector3&in scale = Vector3(1, 1, 1), const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetTriangleMesh), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetConvexHull(Model@+, uint, const Vector3&in scale = Vector3(1, 1, 1), const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetConvexHull), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetTriangleMesh(Model@+, uint lodLevel = 0, const Vector3&in scale = Vector3(1, 1, 1), const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetTriangleMesh), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetConvexHull(Model@+, uint lodLevel = 0, const Vector3&in scale = Vector3(1, 1, 1), const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetConvexHull), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetCustomConvexHull(CustomGeometry@+, const Vector3&in scale = Vector3(1, 1, 1), const Vector3&in pos = Vector3(), const Quaternion&in rot = Quaternion())", asMETHOD(CollisionShape, SetCustomConvexHull), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetTerrain()", asMETHOD(CollisionShape, SetTerrain), asCALL_THISCALL);
engine->RegisterObjectMethod("CollisionShape", "void SetTransform(const Vector3&in, const Quaternion&in)", asMETHOD(CollisionShape, SetTransform), asCALL_THISCALL);
@ -127,6 +127,7 @@ static void RegisterRigidBody(asIScriptEngine* engine)
engine->RegisterObjectMethod("RigidBody", "void ApplyTorqueImpulse(const Vector3&in)", asMETHOD(RigidBody, ApplyTorqueImpulse), asCALL_THISCALL);
engine->RegisterObjectMethod("RigidBody", "void ResetForces()", asMETHOD(RigidBody, ResetForces), asCALL_THISCALL);
engine->RegisterObjectMethod("RigidBody", "void Activate()", asMETHOD(RigidBody, Activate), asCALL_THISCALL);
engine->RegisterObjectMethod("RigidBody", "void ReAddBodyToWorld()", asMETHOD(RigidBody, ReAddBodyToWorld), asCALL_THISCALL);
engine->RegisterObjectMethod("RigidBody", "Vector3 GetVelocityAtPoint(const Vector3&in) const", asMETHOD(RigidBody, GetVelocityAtPoint), asCALL_THISCALL);
engine->RegisterObjectMethod("RigidBody", "void set_mass(float)", asMETHOD(RigidBody, SetMass), asCALL_THISCALL);
engine->RegisterObjectMethod("RigidBody", "float get_mass() const", asMETHOD(RigidBody, GetMass), asCALL_THISCALL);

View File

@ -68,6 +68,7 @@ Terrain::Terrain(Context* context) :
numPatches_(IntVector2::ZERO),
patchSize_(DEFAULT_PATCH_SIZE),
numLodLevels_(1),
smoothing_(false),
visible_(true),
castShadows_(false),
occluder_(false),
@ -98,6 +99,7 @@ void Terrain::RegisterObject(Context* context)
ACCESSOR_ATTRIBUTE(Terrain, VAR_RESOURCEREF, "Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()), AM_DEFAULT);
ATTRIBUTE(Terrain, VAR_VECTOR3, "Vertex Spacing", spacing_, DEFAULT_SPACING, AM_DEFAULT);
ACCESSOR_ATTRIBUTE(Terrain, VAR_INT, "Patch Size", GetPatchSize, SetPatchSizeAttr, int, DEFAULT_PATCH_SIZE, AM_DEFAULT);
ATTRIBUTE(Terrain, VAR_BOOL, "Smooth Height Map", smoothing_, false, AM_DEFAULT);
ACCESSOR_ATTRIBUTE(Terrain, VAR_BOOL, "Is Occluder", IsOccluder, SetOccluder, bool, false, AM_DEFAULT);
ACCESSOR_ATTRIBUTE(Terrain, VAR_BOOL, "Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
ACCESSOR_ATTRIBUTE(Terrain, VAR_BOOL, "Cast Shadows", GetCastShadows, SetCastShadows, bool, false, AM_DEFAULT);
@ -137,6 +139,20 @@ void Terrain::OnSetEnabled()
}
}
void Terrain::SetPatchSize(int size)
{
if (size < MIN_PATCH_SIZE || size > MAX_PATCH_SIZE || !IsPowerOfTwo(size))
return;
if (size != patchSize_)
{
patchSize_ = size;
CreateGeometry();
MarkNetworkUpdate();
}
}
void Terrain::SetSpacing(const Vector3& spacing)
{
if (spacing != spacing_)
@ -148,14 +164,11 @@ void Terrain::SetSpacing(const Vector3& spacing)
}
}
void Terrain::SetPatchSize(int size)
void Terrain::SetSmoothing(bool enable)
{
if (size < MIN_PATCH_SIZE || size > MAX_PATCH_SIZE || !IsPowerOfTwo(size))
return;
if (size != patchSize_)
if (enable != smoothing_)
{
patchSize_ = size;
smoothing_ = enable;
CreateGeometry();
MarkNetworkUpdate();
@ -640,6 +653,9 @@ void Terrain::CreateGeometry()
}
}
if (smoothing_)
SmoothHeightMap();
patches_.Reserve(numPatches_.x_ * numPatches_.y_);
bool enabled = IsEnabledEffective();
@ -703,6 +719,29 @@ void Terrain::CreateGeometry()
}
}
void Terrain::SmoothHeightMap()
{
PROFILE(SmoothHeightMap);
SharedArrayPtr<float> newHeightData(new float[numVertices_.x_* numVertices_.y_]);
for (int z = 0; z < numVertices_.y_; ++z)
{
for (int x = 0; x < numVertices_.x_; ++x)
{
float smoothedHeight = (
GetRawHeight(x - 1, z - 1) + GetRawHeight(x, z - 1) + GetRawHeight(x + 1, z - 1) +
GetRawHeight(x - 1, z) + GetRawHeight(x, z) + GetRawHeight(x + 1, z) +
GetRawHeight(x - 1, z + 1) + GetRawHeight(x, z + 1) + GetRawHeight(x + 1, z + 1)
) / 9.0f;
newHeightData[z * numVertices_.x_ + x] = smoothedHeight;
}
}
heightData_ = newHeightData;
}
void Terrain::CreateIndexData()
{
PROFILE(CreateIndexData);

View File

@ -56,6 +56,8 @@ public:
void SetPatchSize(int size);
/// Set vertex (XZ) and height (Y) spacing.
void SetSpacing(const Vector3& spacing);
/// Set smoothing of heightmap.
void SetSmoothing(bool enable);
/// Set heightmap image. Dimensions should be a power of two + 1. Uses 8-bit grayscale, or optionally red as MSB and green as LSB for 16-bit accuracy. Return true if successful.
bool SetHeightMap(Image* image);
/// Set material.
@ -91,6 +93,8 @@ public:
const IntVector2& GetNumVertices() const { return numVertices_; }
/// Return heightmap size in patches.
const IntVector2& GetNumPatches() const { return numPatches_; }
/// Return whether smoothing is in use.
bool GetSmoothing() const { return smoothing_; }
/// Return heightmap image.
Image* GetHeightMap() const;
/// Return material.
@ -148,6 +152,8 @@ public:
private:
/// Fully regenerate terrain geometry.
void CreateGeometry();
/// Filter the heightmap.
void SmoothHeightMap();
/// Create index data shared by all patches.
void CreateIndexData();
/// Return an uninterpolated terrain height value, clamping to edges.
@ -191,6 +197,8 @@ private:
int patchSize_;
/// Number of terrain LOD levels.
unsigned numLodLevels_;
/// Smoothing enable flag.
bool smoothing_;
/// Visible flag.
bool visible_;
/// Shadowcaster flag.

View File

@ -155,9 +155,9 @@ public:
/// Set as a cone.
void SetCone(float diameter, float height, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
/// Set as a triangle mesh.
void SetTriangleMesh(Model* model, unsigned lodLevel, const Vector3& scale = Vector3::ONE, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
void SetTriangleMesh(Model* model, unsigned lodLevel = 0, const Vector3& scale = Vector3::ONE, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
/// Set as a convex hull from Model.
void SetConvexHull(Model* model, unsigned lodLevel, const Vector3& scale = Vector3::ONE, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
void SetConvexHull(Model* model, unsigned lodLevel = 0, const Vector3& scale = Vector3::ONE, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
/// Set as a convex hull from CustomGeometry.
void SetCustomConvexHull(CustomGeometry* custom, const Vector3& scale = Vector3::ONE, const Vector3& position = Vector3::ZERO, const Quaternion& rotation = Quaternion::IDENTITY);
/// Set as a terrain. Only works if the same scene node contains a Terrain component.

View File

@ -550,6 +550,12 @@ void RigidBody::Activate()
body_->activate(true);
}
void RigidBody::ReAddBodyToWorld()
{
if (body_ && inWorld_)
AddBodyToWorld();
}
Vector3 RigidBody::GetPosition() const
{
if (body_)

View File

@ -137,6 +137,8 @@ public:
void ResetForces();
/// Activate rigid body if it was resting.
void Activate();
/// Readd rigid body to the physics world to clean up internal state like stale contacts.
void ReAddBodyToWorld();
/// Return physics world.
PhysicsWorld* GetPhysicsWorld() const { return physicsWorld_; }