Report any bugs here and we'll post fixes
Moderators: Sascha Willems, Thomas
by Lax » Sun Oct 29, 2017 9:06 am
Hello all,
I'm experimenting with newton 3.0 and Ogre3D with soft bodies. There are some some newton sandbox demos, on which I orientate. But I do not understand, how to get the sample working.
I'm using the simplest example, in which I create a simple TetrahedraSoftMesh from a box. But somehow later the massSum is zero and even in newton in 'dgCollisionLumpedMassParticles':
dgFloat32 invMass = dgFloat32(1.0f) / massSum;
because there are no particles, somehow.
When I get the particles via:
const dFloat* const particles = NewtonDeformableMeshGetParticleArray(deformableCollision);
The values are also invalid...
I have no clue how to get that working.
Has somebody an example that does work etc. Or can help me out. Im struggling for days with this topic.
Regards
Lax
-
Lax
-
- Posts: 165
- Joined: Sat Jan 08, 2011 8:24 am
by Julio Jerez » Mon Oct 30, 2017 3:02 pm
Oh It may be broken because I turned my attention to polish some functionality before make a final releases of 3.14
I can take a look and see what is wrong and re enabled the demo.
what are you doing?
-
Julio Jerez
- Moderator
-
- Posts: 12249
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Lax » Tue Oct 31, 2017 12:46 pm
I tried to integrate soft bodies for OgreNewt3.0, which I'm working on.
My test scenario is simple. I create a small box and try to generate a deformable collision.
The procedure takes a long time. I think its because a huge number of points is generated, which is conntrolled in newton in dgMeshEffect2 by the cellsize (currently 0.0125 and cannot be changed). But nevertheless, later when trying to regenerate the Ogre mesh, the particles from the function 'NewtonDeformableMeshGetParticleArray' are broken (invalid values).
-
Lax
-
- Posts: 165
- Joined: Sat Jan 08, 2011 8:24 am
by Julio Jerez » Tue Oct 31, 2017 2:30 pm
it should be very fast, it may required some tweaking.
let us start from the beginning.
you start with a box, can you post the size or better yet the set code you are using
maybe and image so that I can see the mesh you are try to simulate?
Maybe we can recreated I the sandbox and we can go from there?
-
Julio Jerez
- Moderator
-
- Posts: 12249
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Lax » Tue Oct 31, 2017 4:39 pm
The box has a size of 1x1x1 meter, see details in the picture:
http://www.lukas-kalinowski.com/Homepage/wp-content/uploads/softbodyScenario.pngI also have a plane, which is a static collision body.
Code for softbody:
The class TetrahedraDeformableCollision takes a finished collision, to create the skin mesh from and the deformable collision:
- Code: Select all
TetrahedraDeformableCollision::TetrahedraDeformableCollision(const World* world, const NewtonCollision* const collision, int id)
: ConvexCollision(world)
{
NewtonMesh* const skinMesh = NewtonMeshCreateFromCollision(collision);
NewtonMesh* const tetraIsoSurface = NewtonMeshCreateTetrahedraIsoSurface(skinMesh);
NewtonCreateTetrahedraLinearBlendSkinWeightsChannel(tetraIsoSurface, skinMesh);
NewtonDestroyCollision(collision);
m_col = NewtonCreateDeformableSolid(world->getNewtonWorld(), tetraIsoSurface, id);
NewtonCollisionSetUserData(m_col, this);
NewtonMeshDestroy(skinMesh);
NewtonMeshDestroy(tetraIsoSurface);
}
After that I create a body as usual with this new collision.
- Code: Select all
void PhysicsActiveComponent::createSoftBody(void)
{
// Collision must be recreated
Ogre::Vector3 inertia = Ogre::Vector3(1.0f, 1.0f, 1.0f);
Ogre::Vector3 calculatedMassOrigin = Ogre::Vector3::ZERO;
// Create collision for specific collision type
OgreNewt::CollisionPtr collisionPtr = this->createDynamicCollision(inertia, Ogre::Vector3::ZERO, collisionOrienation, calculatedMassOrigin);
// Create from that collision a deformable collision
OgreNewt::CollisionPtr deformableCollisionPtr = this->createDeformableCollision(collisionPtr);
const OgreNewt::MaterialID* materialId = this->physicsBody->getMaterialGroupID();
if (nullptr != this->physicsBody)
{
this->physicsBody->detachNode();
this->physicsBody->removeForceAndTorqueCallback();
this->physicsBody->removeNodeUpdateNotify();
this->physicsBody->removeDestructorCallback();
delete this->physicsBody;
this->physicsBody = nullptr;
}
this->physicsBody = new OgreNewt::Body(this->ogreNewt, deformableCollisionPtr);
if (Ogre::Vector3::ZERO != this->massOrigin->getVector3())
{
calculatedMassOrigin = this->massOrigin->getVector3();
}
this->physicsBody->setPositionOrientation(this->initialPosition, this->initialOrientation);
Ogre::Real weightedMass = this->mass->getReal();
// apply mass and scale to inertia (the bigger the object, the more mass)
inertia *= weightedMass;
this->physicsBody->setMassMatrix(weightedMass, inertia);
// set mass origin
this->physicsBody->setCenterOfMass(calculatedMassOrigin);
// NewtonBodySetMassProperties(this->physicsBody->getNewtonBody(), this->mass->getReal(), deformableCollisionPtr->getNewtonCollision());
this->physicsBody->setLinearDamping(this->linearDamping->getReal());
this->physicsBody->setAngularDamping(this->angularDamping->getVector3());
this->physicsBody->setCustomForceAndTorqueCallback<PhysicsActiveComponent>(&PhysicsActiveComponent::moveCallback, this);
// set user data for ogrenewt
this->physicsBody->setUserData(OgreNewt::Any(dynamic_cast<PhysicsComponent*>(this)));
this->physicsBody->attachNode(this->gameObjectPtr->getSceneNode());
this->physicsBody->setType(this->gameObjectPtr->getCategoryId());
this->physicsBody->setMaterialGroupID(materialId);
}
In the OgreNewt body, I have an update function, which should adapt the mesh according the result particles:
- Code: Select all
void Body::updateDeformableCollision(void)
{
NewtonCollision* deformableCollision = NewtonBodyGetCollision(m_body);
if (NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_DEFORMABLE_SOLID)
{
const dFloat* const particles = NewtonDeformableMeshGetParticleArray(deformableCollision);
int stride = NewtonDeformableMeshGetParticleStrideInBytes(deformableCollision) / sizeof(dFloat);
Ogre::SceneNode* sceneNode = static_cast<Ogre::SceneNode*>(m_node);
Ogre::v1::MeshPtr mesh = static_cast<Ogre::v1::Entity*>(sceneNode->getAttachedObject(0))->getMesh();
//find number of submeshes
unsigned short sub = mesh->getNumSubMeshes();
for (unsigned short i = 0; i < sub; i++)
{
Ogre::v1::SubMesh* subMesh = mesh->getSubMesh(i);
Ogre::v1::VertexData* vertexData;
if (subMesh->useSharedVertices)
{
vertexData = mesh->sharedVertexData[0];
}
else
{
vertexData = subMesh->vertexData[0];
}
Ogre::v1::IndexData* indexData = subMesh->indexData[0];
const Ogre::v1::VertexElement* posElem = vertexData->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::v1::HardwareVertexBufferSharedPtr vbuf = vertexData->vertexBufferBinding->getBuffer(posElem->getSource());
Ogre::v1::HardwareIndexBufferSharedPtr ibuf = indexData->indexBuffer;
float* vertices = static_cast<float *>(vbuf->lock(Ogre::v1::HardwareBuffer::HBL_WRITE_ONLY));
float* indices = static_cast<float *>(ibuf->lock(Ogre::v1::HardwareBuffer::HBL_WRITE_ONLY));
for (int i = 0; i < vertexData->vertexCount; i++)
{
int index = indices[i] * stride;
vertices[i * 3 + 0] = particles[index + 0];
vertices[i * 3 + 1] = particles[index + 1];
vertices[i * 3 + 2] = particles[index + 2];
}
vbuf->unlock();
ibuf->unlock();
}
}
}
-
Lax
-
- Posts: 165
- Joined: Sat Jan 08, 2011 8:24 am
Return to Bugs and Fixes
Who is online
Users browsing this forum: No registered users and 7 guests