When I paste java-code into the message field and put JAVA-tags around it, it is showing correctly in my message window, but as soon as submit the message, something goes wrong. See also:
http://hub.jmonkeyengine.org/forum/topic/buoyancycontrol-code-to-be-used-with-projectedgrid/
Quick demonstration:
[java]package enemyahead;
import com.jme3.bounding.BoundingBox;
import com.jme3.bullet.PhysicsSpace;
import com.jme3.bullet.PhysicsTickListener;
import com.jme3.bullet.control.PhysicsControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.collision.CollisionResults;
import com.jme3.math.Quaternion;
import com.jme3.math.Ray;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
/**
-
@author Arjen
*/
public final class BuoyancyControl extends RigidBodyControl implements PhysicsTickListener, PhysicsControl
{
ShipTest myShip;
Node myHull;
float myScale;
float myMass;
float myDraft;
int qtyCP = 20; // Number of contol points to be used alongside the entire hull (half of them on startboard side , half of them on part side)
Vector3f[] vecControlPoint = new Vector3f[qtyCP]; // Position of control point relative to the ship.
Vector3f[] vecControlPointCalc = new Vector3f[qtyCP]; // Position of control point in world coordinates (for applying forces).
Quaternion shipQuat = new Quaternion(Quaternion.ZERO);
Vector3f shipPos = new Vector3f();
float[] waveHeight = new float[qtyCP];
float[] cpHeight = new float[qtyCP];
// Strength of the wave at every cross-section of the ship (displacement). Still hard-coded, but should be calculated in the future:
float[] waveStrength = {0.03f, 0.03f, 0.04f, 0.05f, 0.1f, 0.1f, 0.07f, 0.04f, 0.03f, 0.01f, 0.01f, 0.03f, 0.04f, 0.07f, 0.1f, 0.1f, 0.05f, 0.04f, 0.03f, 0.03f};
Vector3f waterImpulseForce = new Vector3f(), waterImpulseLocation = new Vector3f();
float waveForce; // Force applied to follow waves.
/**
* Adds an empty BuoyancyControl.
*/
public BuoyancyControl()
{
}
/**
* Adds a BuoyancyControl to the ship object.
*
* @param ship The ship class object in which the ship is assembled.
* @param hull Node which holds the hull of the ship in the Ship class.
* @param scale Scale as set in the Ship class.
* @param mass Float holding the ships mass.
* @param draft Float holding the ships draft (distance from waterline to the bottom of the keel).
* @return none
*/
public BuoyancyControl(ShipTest ship, Node hull, float scale, float mass, float draft)
{
super(mass);
myShip = ship;
myHull = hull;
myScale = scale;
myMass = mass;
myDraft = draft/myScale;
waveForce = myMass*myShip.gravity;
for (int i = 0; i<qtyCP; i++)
{
vecControlPoint[i] = new Vector3f(Vector3f.ZERO);
}
createControlPoints();
}
@Override
public void setPhysicsSpace(PhysicsSpace space)
{
super.setPhysicsSpace(space);
if (space != null)
{
space.addTickListener(this);
}
}
public void prePhysicsTick(PhysicsSpace space, float tpf)
{
checkWavePos();
}
public void physicsTick(PhysicsSpace space, float tpf)
{
followWave(tpf);
}
@Override
public void update(float tpf)
{
super.update(tpf);
}
/**
* Here we are creating the positions of the control points which we use to calculate the depth of the hull in relation to the water.
*/
public void createControlPoints()
{
float myLength = ((BoundingBox)myHull.getWorldBound()).getXExtent() / myScale; // Lenght of the hull (half of its lenght).
float xCoor; // X-coordinate for the control point
float zCoor; // Z-coordinate for the control point
for (int i=0; i 0)
{
zCoor = results.getCollision(0).getDistance()/myScale; // Define the Z-coordinate for this cross-section.
}
else
{
zCoor = 0f; // To prevent 'out of bound array error' when there is no collision (especially at stern and bow, because mostly the waterline is shorter then the overal lenght of the hull).
}
vecControlPoint[i].set(xCoor, 0f, zCoor); // Set the coordinates for the given control point on starboard side.
vecControlPoint[i+qtyCP/2].set(xCoor, 0f, -zCoor); // Set the coordinates for the given control point on port side.
vecControlPointCalc[i] = new Vector3f(xCoor, 0f, zCoor); // Set the coordinates for the given calculated control point on starboard side.
vecControlPointCalc[i+qtyCP/2] = new Vector3f(xCoor, 0f, -zCoor); // Set the coordinates for the given calculated control point on port side.
}
for (int i=0; i<qtyCP; i++)
{
waveHeight[i] = 0f; // Fill/create the wave height values.
cpHeight[i] = 0f; // Fill/create the control point height values.
}
}
/**
* Check the height of the waves for each control point location.
*/
public void checkWavePos()
{
shipQuat.set(this.getPhysicsRotation()); // Store the physic body's rotation.
shipPos.set(this.getPhysicsLocation()); // Store the physic body's location
// For every control point, calculate the world location, then get the height of the wave at that world location by accessing the waterheight generator, then set the control point height of that location:
for (int i=0; i<qtyCP; i++)
{
vecControlPointCalc[i] = shipPos.add(shipQuat.mult(vecControlPoint[i]).mult(myScale));
waveHeight[i] = myShip.myGame.whGEN.getHeight(vecControlPointCalc[i].x, vecControlPointCalc[i].z, myShip.myGame.grid.myTime);
cpHeight[i] = vecControlPointCalc[i].y;
}
}
/**
* Apply the forces which make the hull follow the waves:
*/
public void followWave(float tpf)
{
shipPos.set(this.getPhysicsLocation()); // Store the physic body's location
// Process every control point:
for (int i=0; i -myDraft) // Only apply force when part of the ship is in the water, else only gravity will have to do its job.
{
waterImpulseForce.set(0, waveStrength[i]*waveForce*(1+(waveHeight[i]-cpHeight[i]))*tpf, 0); // Set the force.
waterImpulseLocation.set(vecControlPointCalc[i].subtract(shipPos)); // Set the location the force has to be applied to.
this.applyImpulse(waterImpulseForce, waterImpulseLocation); // Apply the force to the hull.
}
}
}
}[/java]
This code should be similar to the one found here: http://members.home.nl/arjen-vanderbeek/BuoyancyControl.txt
[EDIT] Near line 189 and 269 there is something going wrong. It seems to be related to the FOR-loops?