Thanks for answering:
In the configuration initial table looks like this:
basic,testobj,platform1,entity,platform1node,basiccube.mesh,material,climbertexture,position,0,0,11,
rotation,0,0,0,scale,1,1,1,showboundingbox,true,force,physics01,mass,1,activationtype,alwayson,restitution,1,hitboxtype,convexmesh:own
The bulletspecific configuration starts after the "force" but the initial use the whole list.
the seachinvector function simply search in this list, and return the position of the word. so if you search the word "hitboxtype" then the tablecord+1 will be the "convexmesh:own"
I know I could write it more elegantly, but it's a several years old function, I used it all over the program and it works pretty good, plus I still have a bunch of work with the system, this one have low priority.
I checked all of the input data and it looks pretty valid to me(maybe I forgot something?):
Code: Select all
20:16:20: the konvex one
20:16:20: pt[0]: x: 0.5 y: -0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[1]: x: 0.5 y: -0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[2]: x: -0.5 y: -0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[3]: x: -0.5 y: -0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[4]: x: 0.5 y: 0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[5]: x: -0.5 y: 0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[6]: x: -0.5 y: 0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[7]: x: 0.499999 y: 0.5z: 0.499999
20:16:20: ______________________________________________
20:16:20: pt[8]: x: 0.5 y: -0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[9]: x: 0.5 y: 0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[10]: x: 0.499999 y: 0.5z: 0.499999
20:16:20: ______________________________________________
20:16:20: pt[11]: x: 0.5 y: -0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[12]: x: 0.5 y: -0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[13]: x: 0.499999 y: 0.5z: 0.499999
20:16:20: ______________________________________________
20:16:20: pt[14]: x: -0.5 y: 0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[15]: x: -0.5 y: -0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[16]: x: -0.5 y: -0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[17]: x: -0.5 y: 0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[18]: x: -0.5 y: 0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[19]: x: -0.5 y: -0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[20]: x: 0.5 y: 0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[21]: x: 0.5 y: -0.5z: 0.5
20:16:20: ______________________________________________
20:16:20: pt[22]: x: -0.5 y: -0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: pt[23]: x: -0.5 y: 0.5z: -0.5
20:16:20: ______________________________________________
20:16:20: concave: false
20:16:20: vertex_count: 24
20:16:20: shapetype: 4
20:16:20: mass: 1
20:16:20: margin: 0.1
20:16:20: LocalScaling 1 - 1 - 1
20:16:20: localinertia 0 - 0 - 0
20:16:20: aabbmin -0.64 - -0.64 - -11.64
20:16:20: aabbmax 0.64 - 0.64 - -10.3658
20:16:20: position: 0 - 0 - -11
20:16:20: quaternion: 0 - 0 - 0 - 1
Here is the whole algorithm of the convexshape generator, I show only the passing part last time:
Code: Select all
void Rigidbody::entitytoconvexshape3(Ogre::Entity *Entity)
{
//unsigned int ticket = threadogre.GetPlaceHolder();
functions.log("the konvex one");
// Each entity added need to reset size and radius
// next time getRadius and getSize are asked, they're computed.
bool added_shared = false;
size_t vertex_count = 0, index_count = 0;
size_t current_offset = 0;
size_t shared_offset = 0;
Ogre::MeshPtr mesh = Entity->getMesh();
Ogre::Node* nNode = Entity->getParentNode();
//ettm.mTransform = transform;
Ogre::Vector3 mScale = nNode ? nNode->getScale() : Ogre::Vector3(1, 1, 1);
for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
{
Ogre::SubMesh* submesh = mesh->getSubMesh(i);
// We only need to add the shared vertices once
if (submesh->useSharedVertices)
{
if (!added_shared)
{
vertex_count += mesh->sharedVertexData->vertexCount;
added_shared = true;
}
}
else
{
vertex_count += submesh->vertexData->vertexCount;
}
// Add the indices
index_count += submesh->indexData->indexCount;
}
Ogre::Vector3* vertices = new Ogre::Vector3[vertex_count];
added_shared = false;
btTriangleMesh *mTriMesh = new btTriangleMesh();
for (unsigned short i = 0; i < mesh->getNumSubMeshes(); ++i)
{
Ogre::SubMesh* submesh = mesh->getSubMesh(i);
Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
if ((!submesh->useSharedVertices) || (submesh->useSharedVertices && !added_shared))
{
if (submesh->useSharedVertices)
{
added_shared = true;
shared_offset = current_offset;
}
const Ogre::VertexElement* posElem =
vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
Ogre::HardwareVertexBufferSharedPtr vbuf =
vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* vertex =
static_cast<unsigned char*>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
// There is _no_ baseVertexPointerToElement() which takes an Ogre::Real or a double
// as second argument. So make it float, to avoid trouble when Ogre::Real will
// be comiled/typedefed as double:
//Ogre::Real* pReal;
float* pReal;
int endj = 0;
//collisionshape = new btBoxShape(btVector3(btScalar(1), btScalar(1), btScalar(1)));
//return;
collisionshape = new btConvexHullShape();
for (size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
{
posElem->baseVertexPointerToElement(vertex, &pReal);
btVector3 pt(pReal[0], pReal[1], pReal[2]);
functions.log("pt["+ functions.converttostring(j)+"]: x: " + functions.converttostring(pt.getX()) + " y: " + functions.converttostring(pt.getY()) + "z: " + functions.converttostring(pt.getX()));
functions.log("______________________________________________");
((btConvexHullShape*)collisionshape)->addPoint(pt);
}
collisionshape->calculateSerializeBufferSize();
functions.log("concave: "+functions.converttostring(collisionshape->isConcave(),""));
collisionshape->setMargin(0.1f);
functions.log("vertex_count: " + functions.converttostring(vertex_count));
vbuf->unlock();
//next_offset += vertex_data->vertexCount;
}
}
}
and here is the full initial code:
Code: Select all
bool Rigidbody::initial(int index, Ogre::Node *node,Ogre::Entity *&Entity, vector<string> configuration)
{
name = configuration[2];
itemindex = index;
itemnode = node;
string shapetype = "box";
if (Entity != nullptr)
{
entity = Entity;
entityisvalid = true;
}
int tablecoord = -1;
if (functions.searchinvector("hitboxtype", configuration, tablecoord)) shapetype = configuration[tablecoord + 1];
size = Ogre::Vector3(1, 1, 1);
position = itemnode->_getDerivedPosition();
quaternion = itemnode->_getDerivedOrientation();
mass = 0;
localinertia = btVector3(0, 0, 0);
radius = 1;
//ha gömb, akkor a rádiusz még az element definíciójában lessz hozzáadva radsize,value szerkezettel
if (functions.searchinvector("radsize", configuration, tablecoord))radius = functions.converttodouble(configuration[tablecoord + 1]);
if (functions.searchinvector("size", configuration, tablecoord))
{
size.x = functions.converttodouble(configuration[tablecoord + 1]);
size.y = functions.converttodouble(configuration[tablecoord + 2]);
size.z = functions.converttodouble(configuration[tablecoord + 3]);
}
if (functions.searchinvector("mass", configuration, tablecoord)) mass = functions.converttofloat(configuration[tablecoord + 1]);
if (functions.searchinvector("localinertia", configuration, tablecoord))
{
localinertia.setX(btScalar(functions.converttofloat(configuration[tablecoord + 1])));
localinertia.setY(btScalar(functions.converttofloat(configuration[tablecoord + 2])));
localinertia.setZ(btScalar(functions.converttofloat(configuration[tablecoord + 3])));
}
btTransform transform; transform.setIdentity();
transform.setOrigin(btVector3(btScalar(position.x), btScalar(position.y), btScalar(position.z)));//position
transform.setRotation(btQuaternion(btScalar(quaternion.x), btScalar(quaternion.y), btScalar(quaternion.z), btScalar(quaternion.w)));
btDefaultMotionState *motionstate = new btDefaultMotionState(transform);
_setcollisionshape(shapetype);
int shapenumber = collisionshape->getShapeType();
btVector3 aabbmin,aabbmax,scaaling;
collisionshape->getAabb(transform,aabbmin, aabbmax);
scaaling=collisionshape->getLocalScaling();
functions.log("shapetype: " + functions.converttostring(shapenumber));
functions.log("mass: " + functions.converttostring(mass));
functions.log("margin: "+ functions.converttostring(collisionshape->getMargin()));
functions.log("LocalScaling " + functions.converttostring(scaaling.getX()) + " - " + functions.converttostring(scaaling.getY()) + " - " + functions.converttostring(scaaling.getZ()));
functions.log("localinertia " + functions.converttostring(localinertia.getX()) + " - " + functions.converttostring(localinertia.getY()) + " - " + functions.converttostring(localinertia.getZ()));
functions.log("aabbmin " + functions.converttostring(aabbmin.getX()) + " - " + functions.converttostring(aabbmin.getY()) + " - " + functions.converttostring(aabbmin.getZ()));
functions.log("aabbmax " + functions.converttostring(aabbmax.getX()) + " - " + functions.converttostring(aabbmax.getY()) + " - " + functions.converttostring(aabbmax.getZ()));
functions.log("position: " + functions.converttostring(position.x) + " - " + functions.converttostring(position.y) + " - " + functions.converttostring(position.z));
functions.log("quaternion: " + functions.converttostring(quaternion.x) + " - " + functions.converttostring(quaternion.y) + " - " + functions.converttostring(quaternion.z) + " - " + functions.converttostring(quaternion.w));
btVector3 ascale(btScalar(1), btScalar(1), btScalar(1));
collisionshape->setLocalScaling(ascale);
collisionshape->calculateLocalInertia(mass, localinertia);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionstate, collisionshape, localinertia);
double friction = 1, rollingfriction = 0.5;
if (functions.searchinvector("friction", configuration, tablecoord)) friction = functions.converttodouble(configuration[tablecoord + 1]);
if (functions.searchinvector("rollingfriction", configuration, tablecoord)) rollingfriction == functions.converttodouble(configuration[tablecoord + 1]);
rbInfo.m_friction = btScalar(friction);
rbInfo.m_rollingFriction = btScalar(rollingfriction);
body = new btRigidBody(rbInfo);
body->setUserPointer(itemnode);
body->setUserIndex(index);
if (functions.searchinvector("activationtype", configuration, tablecoord))
{
setactivationtype(configuration[tablecoord + 1]);
}
float restitution = 0;
if (functions.searchinvector("restitution", configuration, tablecoord)) restitution = functions.converttofloat(configuration[tablecoord + 1]);
setrestitution(restitution);
bool anctive = true;
bool nedforce = true;
data::boolvector3 nedforces = data::boolvector3(true, true, true);
bool nedroll = true;
data::boolvector3 nedrolls = data::boolvector3(true, true, true);
//bool active = true;
//if (functions.searchinvector("active", configuration, tablecoord)) active = functions.converttobool(configuration[tablecoord + 1]);
if (functions.searchinvector("active", configuration, tablecoord)) anctive = functions.converttobool(configuration[tablecoord + 1]);
if (functions.searchinvector("needforce", configuration, tablecoord)) nedforce = functions.converttobool(configuration[tablecoord + 1]);
if (functions.searchinvector("activeforcedirection", configuration, tablecoord))
{
nedforces.x = functions.converttobool(configuration[tablecoord + 1]);
nedforces.y = functions.converttobool(configuration[tablecoord + 2]);
nedforces.z = functions.converttobool(configuration[tablecoord + 3]);
}
if (functions.searchinvector("needroll", configuration, tablecoord))nedroll = functions.converttobool(configuration[tablecoord + 1]);
if (functions.searchinvector("activerolldirection", configuration, tablecoord))
{
nedrolls.x = functions.converttobool(configuration[tablecoord + 1]);
nedrolls.y = functions.converttobool(configuration[tablecoord + 2]);
nedrolls.z = functions.converttobool(configuration[tablecoord + 3]);
}
setactive(anctive);
needmove(nedforce);
setactivemovedirections(nedforces);
needroll(nedroll);
setactiverollingdirections(nedrolls);
if (functions.searchinvector("hitboxscale", configuration, tablecoord))
{
data::vector3 scale(functions.converttofloat(configuration[tablecoord + 1]),functions.converttofloat(configuration[tablecoord + 2]), functions.converttofloat(configuration[tablecoord + 3]));
sethitboxscale(scale);
}
if (functions.searchinvector("flags", configuration, tablecoord))
{
vector<string> flags = functions.getvectorline(configuration, "flags", "flags:end");
for (int i = 0; i < flags.size(); i++)
{
setcollisionflag(flags[i]);
}
}
return true;
}
There is a functions between the initial and the entitytoconvexshape3, but it's like the same if you call it directly from the initial function, nothing extra in there, just some if functions:
Code: Select all
bool Rigidbody::_setcollisionshape(string shapetype)
{
if (shapetype == "box")
{
collisionshape = new btBoxShape(btVector3(btScalar(size.x), btScalar(size.y), btScalar(size.z)));
return true;
}
if (shapetype == "capsule")
{
collisionshape = new btCapsuleShape(btScalar(size.x / 2), btScalar(size.y));
return true;
}
if (shapetype == "cylinder")
{
collisionshape = new btCylinderShape(btVector3(btScalar(size.x), btScalar(size.y), btScalar(size.z)));
return true;
}
if (shapetype == "plane")
{
collisionshape = new btBoxShape(btVector3(btScalar(size.x), btScalar(0), btScalar(size.z)));
return true;
}
if (shapetype == "sphere")
{
collisionshape = new btSphereShape(btScalar(radius));
return true;
}
if (functions.Getstringbefore(shapetype, ":", false) == "convexmesh")
{
string entityname = functions.Getstringafter(shapetype, ":", false);
if (entityname == "own")
{
if (entityisvalid)
{
//collisionshape = new btConvexHullShape();
//collisionshape = entitytoconvexshape3(entity);
entitytoconvexshape3(entity);
return true;
}
}
else if (entityname != "")
{
Resultelement parent = gamesets.getelement(entityname);
if (parent.exist && parent.element->gettype() == "entity")
{
Ogre::Entity *entity;
parent.element->getentity(entity);
collisionshape = new btConvexHullShape();
//btConvexHullShape *convexshape = entitytoconvexshape(entity);
//collisionshape = new btConvexTriangleMeshShape(entitytoconvexshape(entity));
//collisionshape = ;
return true;
}
}
}
if (functions.Getstringbefore(shapetype, ":", false) == "statictrianglemesh")
{
string entityname = functions.Getstringafter(shapetype, ":", false);
if (entityname == "own")
{
if (entityisvalid)
{
functions.log("entity name: "+entity->getName());
btTriangleMesh* btrianglemesh = entitytobtTriangleMesh(entity);
functions.log("got the trianglemesh.");
collisionshape = new btBvhTriangleMeshShape(btrianglemesh, true);
return true;
}
}
else if (entityname != "")
{
Resultelement parent = gamesets.getelement(entityname);
if (parent.exist && parent.element->gettype() == "entity")
{
Ogre::Entity *entity;
parent.element->getentity(entity);
btTriangleMesh* btrianglemesh = new btTriangleMesh();
btrianglemesh = entitytobtTriangleMesh(entity);
collisionshape = new btBvhTriangleMeshShape(btrianglemesh, true);
return true;
}
}
}
return false;
}