I've seen that the engine features an fluidvolume and i thought that would be perfect for a little boat racing game. The boat consists of a simple box entity and it's motor is represented by a LinearAxisMotor. The axis of that motor is used to steer the boat. The problem is that my solution seems to work only for very low goal velocities of the motor. No matter what values I use (linear + angular damping, density,...) the boat starts rotating and is going totaly crazy. Can you give me some hints how to get a stable solution for a fast boat and how to steer it? Here's my current code:
Code: Select all
using System;
using System.Collections.Generic;
using BEPUphysics.Collidables;
using BEPUphysics.CollisionShapes;
using BEPUphysics.CollisionShapes.ConvexShapes;
using BEPUphysics.Constraints.TwoEntity.Motors;
using BEPUphysics.DataStructures;
using BEPUphysics.Entities;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.MathExtensions;
using BEPUphysics.UpdateableSystems;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using BEPUphysics.Materials;
namespace BEPUphysicsDemos.Demos
{
/// <summary>
/// Blocks floating in a viscous fluid.
/// </summary>
public class BuoyancyDemo : StandardDemo
{
/// <summary>
/// Constructs a new demo.
/// </summary>
/// <param name="game">Game owning this demo.</param>
public BuoyancyDemo(DemosGame game)
: base(game)
{
var tris = new List<Vector3[]>();
float basinWidth = 500;
float basinLength = 500;
float basinHeight = 16;
float waterHeight = 15;
//Remember, the triangles composing the surface need to be coplanar with the surface. In this case, this means they have the same height.
tris.Add(new[]
{
new Vector3(-basinWidth / 2, waterHeight, -basinLength / 2), new Vector3(basinWidth / 2, waterHeight, -basinLength / 2),
new Vector3(-basinWidth / 2, waterHeight, basinLength / 2)
});
tris.Add(new[]
{
new Vector3(-basinWidth / 2, waterHeight, basinLength / 2), new Vector3(basinWidth / 2, waterHeight, -basinLength / 2),
new Vector3(basinWidth / 2, waterHeight, basinLength / 2)
});
var fluid = new FluidVolume(Vector3.Up, -9.81f, tris, waterHeight, 0.8f, 0.8f, 0.9f, Space.BroadPhase.QueryAccelerator, Space.ThreadManager);
//fluid.FlowDirection = Vector3.Right;
//fluid.FlowForce = 80;
//fluid.MaxFlowSpeed = 50;
Space.Add(fluid);
game.ModelDrawer.Add(fluid);
boat = new Box(new Vector3(0, 15, 0), 5, 1, 3, 2);
Space.Add(boat);
motor = new LinearAxisMotor(boat, null, new Vector3(-20,0,0), Vector3.Zero, new Vector3(1, 0, 0));
motor.IsActive = false;
motor.Settings.Mode = MotorMode.VelocityMotor;
motor.Settings.VelocityMotor.GoalVelocity = 10;
motor.Settings.VelocityMotor.Softness *= 10;
Space.Add(motor);
game.Camera.Position = new Vector3(0, waterHeight + 5, 35);
}
private LinearAxisMotor motor;
private Entity boat;
public override void Update(float dt)
{
var state = Keyboard.GetState();
motor.IsActive = state.IsKeyDown(Keys.Up);
if(state.IsKeyDown(Keys.Left))
{
motor.Axis = new Vector3(1,0,0.2f);
}
else if (state.IsKeyDown(Keys.Right))
{
motor.Axis = new Vector3(1, 0, -0.2f);
}
else
{
motor.Axis = new Vector3(1,0,0);
}
base.Update(dt);
}
/// <summary>
/// Gets the name of the simulation.
/// </summary>
public override string Name
{
get { return "Buoyancy"; }
}
}
}