this area += dp1 * dp0;
is a cross product
area += crossproduct (dp1, dp0);
Moderators: Sascha Willems, walaber
kallaspriit wrote:Convex collision, does it matter?
#ifndef MESHAREACALCULATOR_H
#define MESHAREACALCULATOR_H
#include <OgreNewt.h>
#include <Ogre.h>
class MeshAreaCalculator
{
public:
static float getAreaOf(OgreNewt::Body* body, Ogre::Vector3 dir);
static float getAreaAgainstWind(OgreNewt::Body* body);
float calculateArea(OgreNewt::Body* body, Ogre::Vector3 dir);
Ogre::Vector3 getDir() { return direction; };
void addArea(float sub) { area += sub; };
private:
static void calculateArea(void* userData, int vertexCount, const float* faceVertices, int id);
Ogre::Vector3 direction;
float area;
};
#endif // MESHAREACALCULATOR_H
#include "MeshAreaCalculator.h"
float MeshAreaCalculator::calculateArea(OgreNewt::Body* body, Ogre::Vector3 dir)
{
direction = dir;
float matrix[16];
NewtonBodyGetMatrix(body->getNewtonBody(), &matrix[0]);
float squaredMagnitude = direction.squaredLength();
if(squaredMagnitude > 0.001f)
{
direction.normalise();
NewtonCollisionForEachPolygonDo(NewtonBodyGetCollision(body->getNewtonBody()), &matrix[0], calculateArea, this);
}
return area / 2.0f; // area calculated is twice as big
}
float MeshAreaCalculator::getAreaOf(OgreNewt::Body* body, Ogre::Vector3 dir)
{
MeshAreaCalculator* calc = new MeshAreaCalculator;
float area = calc->calculateArea(body, dir);
delete calc;
return area;
}
float MeshAreaCalculator::getAreaAgainstWind(OgreNewt::Body* body)
{
return getAreaOf(body, body->getVelocity());
}
void MeshAreaCalculator::calculateArea(void* userData, int vertexCount, const float* faceVertices, int id)
{
Ogre::Vector3 area(0.0f, 0.0f, 0.0f);
Ogre::Vector3 p0(faceVertices[0 * 3 + 0], faceVertices[0 * 3 + 1], faceVertices[0 * 3 + 2]);
Ogre::Vector3 p1(faceVertices[1 * 3 + 0], faceVertices[1 * 3 + 1], faceVertices[1 * 3 + 2]);
Ogre::Vector3 dp0(p1 - p0);
for(int i = 2; i < vertexCount; i++)
{
Ogre::Vector3 p1(faceVertices[i * 3 + 0], faceVertices[i * 3 + 1], faceVertices[i * 3 + 2]);
Ogre::Vector3 dp1(p1 - p0);
//area += dp1 * dp0;
area += dp1.crossProduct(dp0);
dp0 = dp1;
}
MeshAreaCalculator* areaInfo = (MeshAreaCalculator*)userData;
Ogre::Real value = area.dotProduct(areaInfo->getDir());
if(value > 0.0f)
{
areaInfo->addArea(value);
}
}
void ForceCallback::forceCallback(OgreNewt::Body* body, float timeStep, int threadIndex)
{
Ogre::Vector3 windVelocity(0.0f, 0.0f, 0.0f);
Ogre::Real mass;
Ogre::Vector3 inertia;
body->getMassMatrix(mass, inertia);
Ogre::Real fluidMassDensity = 1.293f;
Ogre::Vector3 objectVelocity = body->getVelocity() - windVelocity;
Ogre::Real dragCoefficent = 0.5f;
Ogre::Real velocityMagnitude = objectVelocity.normalise();
Ogre::Real area = MeshAreaCalculator::getAreaOf(body, objectVelocity);
// drag formula
Ogre::Real dragMagnitude = (fluidMassDensity * powf(velocityMagnitude, 2) * dragCoefficent * area) / 2.0f;
Ogre::Vector3 gravityForce(0.0f, -9.8 * mass, 0.0f);
Ogre::Vector3 dragForce = dragMagnitude * objectVelocity; // velocity is normalised
body->addForce(gravityForce - dragForce);
}
Users browsing this forum: No registered users and 2 guests