Physicalize Entity/static Object

#1
Hi, I try to create an object dans physicalize it. It's not my own code, so I didn't do the structure.
there are main function used, the first one, wich initiate the save in cfg format of a fusions of meshes to create a building. And after, load for this .cfg to create an entity with this object:

Code: Select all

string name = string().Format("building%d", nbBuildings); string path = string().Format("assets/objects/generated/building%d.cgf", nbBuildings); SaveBuilding(path); SEntitySpawnParams params; params.nFlags = ENTITY_FLAG_SPAWNED; params.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("RigidBodyEx"); params.sName = name; params.vPosition = GetEntity()->GetPos(); params.qRotation = GetEntity()->GetRotation(); params.vScale = GetEntity()->GetScale(); IEntity * newBuilding = gEnv->pEntitySystem->SpawnEntity(params); newBuilding->SetStatObj(gEnv->p3DEngine->LoadStatObj(path), 0, true); newBuilding->SetMaterial(materialBricks); gEnv->pEntitySystem->AddEntityToLayer(m_DBSelectedBuildings.begin()->second, newBuilding->GetId()); nbBuildings++;
And the second one, the function to save in cfg and make the fusion between meshes:

Code: Select all

void SaveBuilding(string a_path) { XmlNodeRef rootNode = GetISystem()->CreateXmlNode("building"); rootNode->setAttr("style", m_style); rootNode->setAttr("baseCFG", getCFG(m_surfaces[m_idxSurface].getEntityId())); rootNode->setAttr("currentCFG", a_path); string path = a_path.substr(0, a_path.length() - 3); path += "xml"; SubSetMap.clear(); IStatObj *pObject = gEnv->p3DEngine->CreateStatObj(); pObject->SetFlags(STATIC_OBJECT_GENERATED); pObject->AddRef(); IIndexedMesh *pMergedMesh = pObject->GetIndexedMesh(true); pMergedMesh->SetVertexCount(0); pMergedMesh->SetFaceCount(0); pMergedMesh->SetTexCoordCount(0); assert(pMergedMesh); int totalVertices = 0, totalFaces = 0; std::vector<VertexInfo> infosVert = std::vector<VertexInfo>(); std::map<int, SubSetInfo> infosSubset = std::map<int, SubSetInfo>(); string log = ""; float lastLength = 0; for (int floorIndex = 0; floorIndex < m_bricks.size(); floorIndex++) { XmlNodeRef floorNode = rootNode->createNode("floor"); for (int facadeIndex = 0; facadeIndex < m_bricks[floorIndex].size(); facadeIndex++) { XmlNodeRef facadeNode = rootNode->createNode("facade"); for (int brickIndex = 0; brickIndex < m_bricks[floorIndex][facadeIndex].size(); brickIndex++) { Enodo::DrawingBoard::Brick * brick = m_bricks[floorIndex][facadeIndex][brickIndex]; XmlNodeRef brickNode = rootNode->createNode("brick"); brickNode->setAttr("position", brick->GoalPos); brickNode->setAttr("model", brick->model); brickNode->setAttr("id", brick->id); brickNode->setAttr("coef", brick->m_coeff); facadeNode->addChild(brickNode); if (brick->pEnt) { IStatObj * pNewObject = brick->pEnt->GetStatObj(0); IIndexedMesh * pSourceMesh = pNewObject->GetRenderMesh()->GetIndexedMesh(); totalVertices += pSourceMesh->GetVertexCount(); totalFaces += pSourceMesh->GetFaceCount(); if (pSourceMesh) { AppendMesh(pSourceMesh, pMergedMesh, brick->pEnt, brick->GoalPos - m_buildingCenter); } else { gEnv->pLog->Log("[Enodo:DrawingBoard]No Index Mesh for brick in %d %d", floorIndex, facadeIndex); } } floorNode->addChild(facadeNode); } } rootNode->addChild(floorNode); } rootNode->saveToFile(path); Vec3* const vertices = pMergedMesh->GetMesh()->GetStreamPtr<Vec3>(CMesh::POSITIONS); vtx_idx* const indicies = pMergedMesh->GetMesh()->GetStreamPtr<vtx_idx>(CMesh::INDICES); int v0, v1; for (int i = 0; i < pMergedMesh->GetFaceCount(); i++) { if (pMergedMesh->GetMesh()->m_pFaces[i].v[0] == pMergedMesh->GetMesh()->m_pFaces[i].v[1]) { v0 = pMergedMesh->GetMesh()->m_pFaces[i].v[0]; v1 = pMergedMesh->GetMesh()->m_pFaces[i].v[1]; gEnv->pLog->Log("face %d share vertex 0 [%s] and 1 [%s]", i, v0, infosVert[v0].ToString(), v1, infosVert[v1].ToString()); } else if (pMergedMesh->GetMesh()->m_pFaces[i].v[0] == pMergedMesh->GetMesh()->m_pFaces[i].v[2]) { v0 = pMergedMesh->GetMesh()->m_pFaces[i].v[0]; v1 = pMergedMesh->GetMesh()->m_pFaces[i].v[2]; gEnv->pLog->Log("face %d share vertex 0 [%s] and 2 [%s]", i, v0, infosVert[v0].ToString(), v1, infosVert[v1].ToString()); } else if (pMergedMesh->GetMesh()->m_pFaces[i].v[1] == pMergedMesh->GetMesh()->m_pFaces[i].v[2]) { v0 = pMergedMesh->GetMesh()->m_pFaces[i].v[1]; v1 = pMergedMesh->GetMesh()->m_pFaces[i].v[2]; gEnv->pLog->Log("face %d share vertex 1 [%s] and 2 [%s]", i, v0, infosVert[v0].ToString(), v1, infosVert[v1].ToString()); } } //Calc bounding box. then optimize stuff! Whatever that does... gEnv->pLog->Log("calculating bbox"); pMergedMesh->CalcBBox(); gEnv->pLog->Log("optimizing"); pMergedMesh->Optimize(); gEnv->pLog->Log("restoreFaces"); pMergedMesh->RestoreFacesFromIndices(); gEnv->pLog->Log("resulting face number: %d (before %d)", pMergedMesh->GetMesh()->GetFaceCount(), totalFaces); AABB aabb = pMergedMesh->GetBBox(); pObject->SetBBoxMin(pMergedMesh->GetBBox().min); pObject->SetBBoxMax(pMergedMesh->GetBBox().max); pObject->SetMaterial(materialBricks); if (pObject->SaveToCGF(a_path, 0, true)) { gEnv->pLog->Log("CGF Saved"); } else { gEnv->pLog->Log("Error: CGF Not Saved"); } pObject->Invalidate(false); pObject->Release(); }
My problem, it's after all of that, the entity created seem not physicalized, I tryed multiple thing and nothing work. I did not found a clear tutorial on the relation beteween entity, Static Object and physicalization, If you have some link, I am open too.



I found that topic :
https://www.cryengine.com/community_arc ... 4&t=128176

so tried:

Code: Select all

string name = string().Format("building%d", nbBuildings); string path = string().Format("assets/objects/generated/building%d.cgf", nbBuildings); SaveBuilding(path); SEntitySpawnParams params; params.nFlags = ENTITY_FLAG_SPAWNED; params.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("RigidBodyEx"); params.sName = name; params.vPosition = GetEntity()->GetPos(); params.qRotation = GetEntity()->GetRotation(); params.vScale = GetEntity()->GetScale(); IEntity * newBuilding = gEnv->pEntitySystem->SpawnEntity(params); //newBuilding->SetStatObj(gEnv->p3DEngine->LoadStatObj(path), 0, true); newBuilding->SetMaterial(materialBricks); gEnv->pEntitySystem->AddEntityToLayer(m_DBSelectedBuildings.begin()->second, newBuilding->GetId()); newBuilding->LoadGeometry(0, path); gEnv->pEntitySystem->InitEntity(newBuilding, params); SEntityPhysicalizeParams params2; params2.type = PE_STATIC; params2.density = 10; params2.mass = 10; params2.nSlot = -1; // tried 0,1,100, -1 (all) still nothing newBuilding->Physicalize(params2);
but still nothing :/

Re: Physicalize Entity/static Object

#2
New try :

Code: Select all

string name = string().Format("building%d", nbBuildings); string path = string().Format("assets/objects/generated/building%d.cgf", nbBuildings); SaveBuilding(path); SEntitySpawnParams params; params.nFlags = ENTITY_FLAG_SPAWNED; params.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("RigidBodyEx"); params.sName = name; params.vPosition = GetEntity()->GetPos() + Vec3(10,0,0); params.qRotation = GetEntity()->GetRotation(); params.vScale = GetEntity()->GetScale(); IEntity * newBuilding = gEnv->pEntitySystem->SpawnEntity(params,false); newBuilding->LoadGeometry(0, path); gEnv->pEntitySystem->AddEntityToLayer(m_DBSelectedBuildings.begin()->second, newBuilding->GetId()); gEnv->pEntitySystem->InitEntity(newBuilding, params); SEntityPhysicalizeParams params2; params2.type = PE_STATIC; params2.nSlot = -1; newBuilding->Physicalize(params2); nbBuildings++;
the physic it's well, but, the geometry not, if I put newBuilding->LoadGeometry(0, path); after gEnv->pEntitySystem->InitEntity(newBuilding, params);, the geometry it's ok, but not the physic

Re: Physicalize Entity/static Object

#4
WHat is physic proxy please ?

I tried :

Code: Select all

params2.type = PE_RIGID;
But still same problem



I tried to load a part of the building, before the merge of meshes in saveBuilding, and it's work. So the problem come from saveBuilding function. But I didn't understand what can do the problem, because I cannot physicalize an static object without entity, no?

Re: Physicalize Entity/static Object

#7
Thank you, I didn't find : GetPhysicalProxy(); I think it was maybe GetProxy of IEntity, but in EEntityProxy, there is no physic:

Code: Select all

enum EEntityProxy { ENTITY_PROXY_AUDIO, ENTITY_PROXY_AREA, ENTITY_PROXY_BOIDS, ENTITY_PROXY_BOID_OBJECT, ENTITY_PROXY_CAMERA, ENTITY_PROXY_FLOWGRAPH, ENTITY_PROXY_SUBSTITUTION, ENTITY_PROXY_TRIGGER, ENTITY_PROXY_ROPE, ENTITY_PROXY_ENTITYNODE, ENTITY_PROXY_CLIPVOLUME, ENTITY_PROXY_DYNAMICRESPONSE, ENTITY_PROXY_SCRIPT, ENTITY_PROXY_USER, //! Always the last entry of the enum. ENTITY_PROXY_LAST };





For the merge, it's doing by code, to explain, players builds a building from several parts (each got there .cgf); when players have finish, those function are execute.
The function wich do merge is that :

Code: Select all

void CDrawing_Board::SaveBuilding(string a_path) { SubSetMap.clear(); IStatObj *pObject = gEnv->p3DEngine->CreateStatObj(); pObject->SetFlags(STATIC_OBJECT_GENERATED); pObject->AddRef(); IIndexedMesh *pMergedMesh = pObject->GetIndexedMesh(true); pMergedMesh->SetVertexCount(0); pMergedMesh->SetFaceCount(0); pMergedMesh->SetTexCoordCount(0); assert(pMergedMesh); int totalVertices = 0, totalFaces = 0; std::vector<VertexInfo> infosVert = std::vector<VertexInfo>(); std::map<int, SubSetInfo> infosSubset = std::map<int, SubSetInfo>(); string log = ""; float lastLength = 0; for (int floorIndex = 0; floorIndex < m_bricks.size(); floorIndex++) { for (int facadeIndex = 0; facadeIndex < m_bricks[floorIndex].size(); facadeIndex++) { for (int brickIndex = 0; brickIndex < m_bricks[floorIndex][facadeIndex].size(); brickIndex++) { Enodo::DrawingBoard::Brick * brick = m_bricks[floorIndex][facadeIndex][brickIndex]; if (brick->pEnt) { IStatObj * pNewObject = brick->pEnt->GetStatObj(0); IIndexedMesh * pSourceMesh = pNewObject->GetRenderMesh()->GetIndexedMesh(); totalVertices += pSourceMesh->GetVertexCount(); totalFaces += pSourceMesh->GetFaceCount(); if (pSourceMesh) { AppendMesh(pSourceMesh, pMergedMesh, brick->pEnt, brick->GoalPos - m_buildingCenter); } else { gEnv->pLog->Log("[Enodo:DrawingBoard]No Index Mesh for brick in %d %d", floorIndex, facadeIndex); } } } } } Vec3* const vertices = pMergedMesh->GetMesh()->GetStreamPtr<Vec3>(CMesh::POSITIONS); vtx_idx* const indicies = pMergedMesh->GetMesh()->GetStreamPtr<vtx_idx>(CMesh::INDICES); int v0, v1; for (int i = 0; i < pMergedMesh->GetFaceCount(); i++) { if (pMergedMesh->GetMesh()->m_pFaces[i].v[0] == pMergedMesh->GetMesh()->m_pFaces[i].v[1]) { v0 = pMergedMesh->GetMesh()->m_pFaces[i].v[0]; v1 = pMergedMesh->GetMesh()->m_pFaces[i].v[1]; gEnv->pLog->Log("face %d share vertex 0 [%s] and 1 [%s]", i, v0, infosVert[v0].ToString(), v1, infosVert[v1].ToString()); } else if (pMergedMesh->GetMesh()->m_pFaces[i].v[0] == pMergedMesh->GetMesh()->m_pFaces[i].v[2]) { v0 = pMergedMesh->GetMesh()->m_pFaces[i].v[0]; v1 = pMergedMesh->GetMesh()->m_pFaces[i].v[2]; gEnv->pLog->Log("face %d share vertex 0 [%s] and 2 [%s]", i, v0, infosVert[v0].ToString(), v1, infosVert[v1].ToString()); } else if (pMergedMesh->GetMesh()->m_pFaces[i].v[1] == pMergedMesh->GetMesh()->m_pFaces[i].v[2]) { v0 = pMergedMesh->GetMesh()->m_pFaces[i].v[1]; v1 = pMergedMesh->GetMesh()->m_pFaces[i].v[2]; gEnv->pLog->Log("face %d share vertex 1 [%s] and 2 [%s]", i, v0, infosVert[v0].ToString(), v1, infosVert[v1].ToString()); } } gEnv->pLog->Log("calculating bbox"); pMergedMesh->CalcBBox(); gEnv->pLog->Log("optimizing"); pMergedMesh->Optimize(); gEnv->pLog->Log("restoreFaces"); pMergedMesh->RestoreFacesFromIndices(); gEnv->pLog->Log("resulting face number: %d (before %d)", pMergedMesh->GetMesh()->GetFaceCount(), totalFaces); AABB aabb = pMergedMesh->GetBBox(); pObject->SetBBoxMin(pMergedMesh->GetBBox().min); pObject->SetBBoxMax(pMergedMesh->GetBBox().max); pObject->SetMaterial(materialBricks); if (pObject->SaveToCGF(a_path, 0, true)) { gEnv->pLog->Log("CGF Saved"); } else { gEnv->pLog->Log("Error: CGF Not Saved"); } pObject->Invalidate(false); pObject->Release(); }
brick->pEnt is an IEntity
Create like that :

Code: Select all

IStatObj *pObject = gEnv->p3DEngine->LoadStatObj("PATH_TO_A_CGF"); Object->SetFlags(STATIC_OBJECT_GENERATED); Vec3 size = pObject->GetAABB().GetSize(); SEntitySpawnParams params; params.nFlags = ENTITY_FLAG_SPAWNED; params.pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Default"); params.sName = name; params.vPosition = pos; params.vScale = scale; Matrix33 mat; mat.SetRotationXYZ(rot); params.qRotation = Quat(mat); *width = alignX ? size.x*scale.x : size.y*scale.y; pEntity = gEnv->pEntitySystem->SpawnEntity(params); pEntity->SetMaterial(a_mat); pEntity->SetStatObj(pObject, 0, true); SEntityPhysicalizeParams physicalizeParams; physicalizeParams.type = PE_STATIC; pEntity->Physicalize(physicalizeParams); IPhysicalEntity* pe = pEntity->GetPhysics(); if (pe) { pe_action_awake aa; aa.bAwake = 0; pe->Action(&aa); pe_params_foreign_data pfd; pfd.iForeignFlagsOR = PFF_UNIMPORTANT; pe->SetParams(&pfd); } AABB aabb = AABB(); pEntity->GetPhysicsWorldBounds(aabb); size = aabb.GetSize(); scale.z = height / size.z; float distOffset = aabb.GetCenter().z - pEntity->GetPos().z - aabb.GetSize().z / 2.f; distOffset = distOffset*scale.z; Vec3 dir = (aabb.GetCenter() - pEntity->GetPos()).normalized(); dir.x = dir.y = 0; Vec3 newPos = pEntity->GetPos() - dir*distOffset; pEntity->SetPos(newPos); pEntity->SetScale(scale);


EDIT:

Oh, and I forgot AppendMesh was create by my team too

Code: Select all

std::map<int, int> SubSetMap; void AppendMesh(IIndexedMesh * source, IIndexedMesh * target, IEntity *pEntTransform, Vec3 offset) { CMesh copy; copy.CopyFrom(*(source->GetMesh())); Vec3* const vertices = copy.GetStreamPtr<Vec3>(CMesh::POSITIONS); Vec3* const normals = copy.GetStreamPtr<Vec3>(CMesh::NORMALS); vtx_idx* const indicies = copy.GetStreamPtr<vtx_idx>(CMesh::INDICES); SMeshTexCoord* const texcoords = copy.GetStreamPtr<SMeshTexCoord>(CMesh::TEXCOORDS); int vertStartID = target->GetVertexCount(); int normStartID = target->GetVertexCount(); int idxStartID = target->GetIndexCount(); int texStartID = target->GetTexCoordCount(); int vertNb = source->GetVertexCount(); int normNb = source->GetVertexCount(); int idxNb = source->GetIndexCount(); int texNb = source->GetTexCoordCount(); //We offset the indices for (int i = 0; i < copy.GetIndexCount(); i++) { if (indicies[i] >= (vtx_idx)0) { indicies[i] = indicies[i] + (vtx_idx)vertStartID; } } //we recompute the vertices Matrix34 worldTM; AABB aabb = AABB(); gEnv->pLog->Log("brick pos %f %f %f", offset.x, offset.y, offset.z); for (int i = 0; i < copy.GetVertexCount(); i++) { aabb.Add(vertices[i]); quaternion quat = pEntTransform->GetWorldRotation(); vertices[i].x *= pEntTransform->GetScale().x; vertices[i].y *= pEntTransform->GetScale().y; vertices[i].z *= pEntTransform->GetScale().z; vertices[i] = quat*vertices[i]; vertices[i] += offset; normals[i] = quat*normals[i]; normals[i].Normalize(); } target->SetVertexCount(vertStartID + vertNb); target->SetIndexCount(idxStartID + idxNb); target->SetTexCoordCount(texStartID + texNb); memcpy(&(target->GetMesh()->GetStreamPtr<Vec3>(CMesh::POSITIONS)[vertStartID]), vertices, sizeof(Vec3)*vertNb); memcpy(&(target->GetMesh()->GetStreamPtr<Vec3>(CMesh::NORMALS)[normStartID]), normals, sizeof(Vec3)*normNb); memcpy(&(target->GetMesh()->GetStreamPtr<vtx_idx>(CMesh::INDICES)[idxStartID]), indicies, sizeof(vtx_idx)*idxNb); memcpy(&(target->GetMesh()->GetStreamPtr<SMeshTexCoord>(CMesh::TEXCOORDS)[texStartID]), texcoords, sizeof(SMeshTexCoord)*texNb); //we redefine the subMtlIds for (int i = 0; i < source->GetSubSetCount(); i++) { SMeshSubset subset = source->GetSubSet(i); subset.nFirstIndexId += idxStartID; subset.nFirstVertId += vertStartID; int subsetCount = target->GetSubSetCount(); target->SetSubSetCount(subsetCount + 1); target->SetSubsetIndexVertexRanges(subsetCount, subset.nFirstIndexId, subset.nNumIndices, subset.nFirstVertId, subset.nNumVerts); target->SetSubsetMaterialId(subsetCount, subset.nMatID); target->SetSubsetMaterialProperties(subsetCount, subset.nMatFlags, subset.nPhysicalizeType); target->SetSubsetBounds(subsetCount, subset.vCenter, subset.fRadius); SubSetMap[subset.nMatID] = subsetCount; } target->GetMesh()->RecomputeGeometricMeanFaceArea(); target->GetMesh()->RecomputeTexMappingDensity(); gEnv->pLog->Log("number of subset for mesh %d", target->GetSubSetCount()); }
I really have no idea on how physic work in cry engine, didn't found any clear tutorial :/

Re: Physicalize Entity/static Object

#8
primitives::capsule prim;

prim.axis.Set(0,0,1);
prim.center.zero(); prim.r = 0.4f; prim.hh = 0.2f;
IGeometry *pPrimGeom = gEnv->pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::capsule::type, &prim);
phys_geometry *pGeom = gEnv->pPhysicalWorld->GetGeomManager()->RegisterGeometry(pPrimGeom, 0);
pe_geomparams gp;
gp.pos = Vec3(0.0f,0.2f,0.7f);
gp.flags = geom_colltype_foliage;
gp.flagsCollider = 0;
pGeom->nRefCount = 0;
//just some arbitrary id, except 100, which is the main cylinder
GetEntity()->GetPhysics()->AddGeometry(pGeom, &gp, 101);
}
http://docs.aws.amazon.com/lumberyard/l ... intro.html
http://www.crytek.co.kr/confluence/disp ... t+Run-time
https://www.cryengine.com/community_arc ... 40&start=0
http://code.taobao.org/p/CryEngine3_6_3 ... wProxy.cpp
https://github.com/AStopher/Crysis-Wars ... achute.cpp

Who is online

Users browsing this forum: No registered users and 2 guests