bool gkBlenderMeshConverter::convert(void) { if (!m_bmesh->mvert) return false; if (m_bmesh->mface) convert_legacy(); #ifdef BMESH else if(m_bmesh->mpoly) convert_bmesh(); #endif else return false; AssignmentListMap assignMap; bool canAssign = m_bmesh->dvert && m_bobj->parent && m_bobj->parent->type == OB_ARMATURE; if (canAssign) { int dgi = 0; for (Blender::bDeformGroup* dg = (Blender::bDeformGroup*)m_bobj->defbase.first; dg; dg = dg->next, ++dgi) { m_gmesh->createVertexGroup(dg->name); convertBoneAssignments(dgi, assignMap); } } // build materials utArrayIterator<utArray<gkMeshPair> > iter(m_meshtable); while (iter.hasMoreElements()) { gkMeshHashKey& key = iter.peekNext().test; gkSubMesh* val = iter.peekNext().item; Blender::Material* bmat = BlenderMaterial(m_bobj, key.m_matnr); if (key.m_blenderMat) { if (bmat) convertMaterial(bmat, val->getMaterial(), key); } else convertTextureFace(val->getMaterial(), key, (Blender::Image**)key.m_images); if (canAssign) { // build def groups assignBoneAssignments(val, assignMap); } iter.getNext(); } return true; }
void gkBlenderSceneConverter::convertObjectParticles(gkGameObject* gobj, Blender::Object* bobj) { #ifdef OGREKIT_USE_PARTICLE for (Blender::ParticleSystem* ps = (Blender::ParticleSystem*)bobj->particlesystem.first; ps; ps = ps->next) { gkString name = ps->name; gkString pname = GKB_IDNAME(ps->part); gkParticleResource* resource = gkParticleManager::getSingleton().getByName<gkParticleResource>(gkResourceName(pname, m_groupName)); if (!resource) continue; gkGameObjectProperties& gprops = gobj->getProperties(); gkParticleObject* pobj = m_gscene->createParticleObject(gkUtils::getUniqueName(name)); if (pobj) { pobj->setActiveLayer(gobj->isInActiveLayer()); pobj->setLayer(gobj->getLayer()); gkParticleSettingsProperties& sprops = resource->getParticleProperties(); gkParticleSystemProperties& props = pobj->getParticleProperties(); gprops.m_particleObjs.push_back(pobj->getName()); props.m_name = name; props.m_seed = ps->seed; props.m_settings = pname; gkGameObjectProperties& gparticleprops = pobj->getProperties(); gparticleprops.m_parent = gobj->getName(); gparticleprops.m_transform = gobj->getProperties().m_transform; props.m_material = "<gkBuiltin/Halo>"; if (!sprops.m_drawEmitter) gobj->getProperties().m_mode |= GK_INVISIBLE; Blender::Material* ma = BlenderMaterial(bobj, sprops.m_material); if (ma) { props.m_material = GKB_IDNAME(ma); } gkEntity* entity = gobj->getEntity(); if (entity) { props.m_mesh = entity->getMesh(); //pobj->setMaterialName(entity->getMesh()->getFirstMaterial().m_name); } } } #endif }
void gkBlenderSceneConverter::convertObjectMesh(gkGameObject* gobj, Blender::Object* bobj) { GK_ASSERT(gobj->getType() == GK_ENTITY && bobj->data); gkEntity* obj = static_cast<gkEntity*>(gobj); gkEntityProperties& props = obj->getEntityProperties(); Blender::Mesh* me = (Blender::Mesh*)bobj->data; // this is shared for faster conversion times // and better efficiency if (!m_gscene->hasMesh(GKB_IDNAME(me))) { props.m_mesh = m_gscene->createMesh(GKB_IDNAME(me)); gkBlenderMeshConverter meconv(props.m_mesh, bobj, me); meconv.convert(); } else props.m_mesh = m_gscene->getMesh(GKB_IDNAME(me)); props.m_casts = gobj->getProperties().m_physics.isRigidOrDynamic() || !gobj->getProperties().isPhysicsObject(); Blender::Material* matr = BlenderMaterial(bobj, 0); if (matr) props.m_casts = (matr->mode & MA_SHADBUF) != 0; // if it has an action save the initial pose / animation name if (bobj->parent) { Blender::Object* par = bobj->parent; Blender::bAction* act = par->action; if (!act && par->proxy_from) act = par->proxy_from->action; if (act) props.m_startPose = (GKB_IDNAME(act)); } }
void gkBlenderSceneConverter::convertObjectPhysics(gkGameObject* gobj, Blender::Object* bobj) { gkGameObjectProperties& props = gobj->getProperties(); gkPhysicsProperties& phy = props.m_physics; int boundtype; int version = m_file->_getInternalFile()->getVersion(); if ((bobj->gameflag & OB_COLLISION) && bobj->body_type==GK_NO_COLLISION) phy.m_type = GK_STATIC; else { phy.m_type = GK_STATIC; switch (bobj->body_type) { case OB_BODY_TYPE_CHARACTER: phy.m_type = GK_CHARACTER; break; case OB_BODY_TYPE_RIGID: phy.m_type = GK_RIGID; break; case OB_BODY_TYPE_DYNAMIC: phy.m_type = GK_DYNAMIC; break; case OB_BODY_TYPE_NO_COLLISION: phy.m_type = GK_NO_COLLISION; break; case OB_BODY_TYPE_SENSOR : phy.m_type = GK_SENSOR; break; case OB_BODY_TYPE_NAVMESH : phy.m_type = GK_NAVMESH; break; } } if (bobj->type != OB_MESH) { if (!(bobj->gameflag & OB_ACTOR)) phy.m_type = GK_NO_COLLISION; } Blender::Object* parent = bobj->parent; while (parent && parent->parent) parent = parent->parent; if (parent && (bobj->gameflag & OB_CHILD) == 0) phy.m_type = GK_NO_COLLISION; if (!props.isPhysicsObject()) return; if (bobj->gameflag & OB_ACTOR) { props.m_mode |= GK_ACTOR; phy.m_mode |= GK_CONTACT; } if (bobj->gameflag & OB_GHOST) props.m_mode |= GK_GHOST; if (bobj->gameflag & OB_OCCLUDER) props.m_mode |= GK_OCCLUDER; if (bobj->gameflag & OB_CHILD) phy.m_mode |= parent ? GK_COMPOUND_CHILD : GK_COMPOUND; if (bobj->gameflag & OB_COLLISION_RESPONSE) phy.m_mode |= GK_NO_SLEEP; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) phy.m_mode |= GK_LOCK_LINV_X; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) phy.m_mode |= GK_LOCK_LINV_Y; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) phy.m_mode |= GK_LOCK_LINV_Z; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) phy.m_mode |= GK_LOCK_ANGV_X; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) phy.m_mode |= GK_LOCK_ANGV_Y; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) phy.m_mode |= GK_LOCK_ANGV_Z; phy.m_minVel = bobj->min_vel; phy.m_maxVel = bobj->max_vel; phy.m_cpt = bobj->m_contactProcessingThreshold; phy.m_linearDamp = bobj->damping; phy.m_angularDamp = bobj->rdamping; phy.m_mass = bobj->mass; phy.m_radius = bobj->inertia; phy.m_formFactor = bobj->formfactor; phy.m_margin = bobj->margin; if (bobj->col_group>0 && bobj->col_mask>0) { phy.m_colGroupMask = bobj->col_group; phy.m_colMask = bobj->col_mask; phy.m_charStepHeight = bobj->step_height; phy.m_charJumpSpeed = bobj->jump_speed; phy.m_charFallSpeed = bobj->fall_speed; } if (gobj->hasVariable("gk_collisionmask")){ phy.m_colMask = gobj->getVariable("gk_collisionmask")->getValueInt(); } if (gobj->hasVariable("gk_collisiongroup")){ phy.m_colGroupMask = gobj->getVariable("gk_collisiongroup")->getValueInt(); } if (bobj->type == OB_MESH) { Blender::Mesh* me = (Blender::Mesh*)bobj->data; if (me) { Blender::Material* ma = BlenderMaterial(bobj, 0); if (ma) { phy.m_restitution = ma->reflect; phy.m_friction = ma->friction; } } } if (version<=260) boundtype = bobj->boundtype; else boundtype = bobj->collision_boundtype; if (!(bobj->gameflag & OB_BOUNDS)) if (bobj->body_type == OB_BODY_TYPE_STATIC) boundtype = OB_BOUND_TRIANGLE_MESH; else boundtype = OB_BOUND_BOX; switch (boundtype) { case OB_BOUND_BOX: phy.m_shape = SH_BOX; break; case OB_BOUND_SPHERE: phy.m_shape = SH_SPHERE; break; case OB_BOUND_CONE: phy.m_shape = SH_CONE; break; case OB_BOUND_CYLINDER: phy.m_shape = SH_CYLINDER; break; case OB_BOUND_CONVEX_HULL: phy.m_shape = SH_CONVEX_TRIMESH; break; case OB_BOUND_TRIANGLE_MESH: if (bobj->type == OB_MESH) { if (phy.isRigidOrDynamic()) phy.m_shape = SH_GIMPACT_MESH; else phy.m_shape = SH_BVH_MESH; } else phy.m_shape = SH_SPHERE; break; case OB_BOUND_CAPSULE: phy.m_shape = SH_CAPSULE; break; } // setup velocity constraints if (phy.isRigidOrDynamic()) { if (phy.m_minVel > 0.f || phy.m_maxVel > 0.f) { gkLimitVelocityConstraint* vc = new gkLimitVelocityConstraint(); vc->setLimit(gkVector2(phy.m_minVel, phy.m_maxVel)); m_gscene->getConstraintManager()->addConstraint(gobj, vc); } } }
void gkBlenderSceneConverter::convertObjectPhysics(gkGameObject* gobj, Blender::Object* bobj) { gkGameObjectProperties& props = gobj->getProperties(); gkPhysicsProperties& phy = props.m_physics; phy.m_type = GK_STATIC; switch (bobj->body_type) { case OB_BODY_TYPE_RIGID: phy.m_type = GK_RIGID; break; case OB_BODY_TYPE_DYNAMIC: phy.m_type = GK_DYNAMIC; break; case OB_BODY_TYPE_NO_COLLISION: phy.m_type = GK_NO_COLLISION; break; } if (bobj->type != OB_MESH) { if (!(bobj->gameflag & OB_ACTOR)) phy.m_type = GK_NO_COLLISION; } Blender::Object* parent = bobj->parent; while (parent && parent->parent) parent = parent->parent; if (parent && (bobj->gameflag & OB_CHILD) == 0) phy.m_type = GK_NO_COLLISION; if (!props.isPhysicsObject()) return; if (bobj->gameflag & OB_ACTOR) { props.m_mode |= GK_ACTOR; phy.m_mode |= GK_CONTACT; } if (bobj->gameflag & OB_GHOST) props.m_mode |= GK_GHOST; if (bobj->gameflag & OB_OCCLUDER) props.m_mode |= GK_OCCLUDER; if (bobj->gameflag & OB_CHILD) phy.m_mode |= parent ? GK_COMPOUND_CHILD : GK_COMPOUND; if (bobj->gameflag & OB_COLLISION_RESPONSE) phy.m_mode |= GK_NO_SLEEP; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_X_AXIS) phy.m_mode |= GK_LOCK_LINV_X; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_Y_AXIS) phy.m_mode |= GK_LOCK_LINV_Y; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_Z_AXIS) phy.m_mode |= GK_LOCK_LINV_Z; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_X_ROT_AXIS) phy.m_mode |= GK_LOCK_ANGV_X; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_Y_ROT_AXIS) phy.m_mode |= GK_LOCK_ANGV_Y; if (bobj->gameflag2 & OB_LOCK_RIGID_BODY_Z_ROT_AXIS) phy.m_mode |= GK_LOCK_ANGV_Z; phy.m_minVel = bobj->min_vel; phy.m_maxVel = bobj->max_vel; phy.m_cpt = bobj->m_contactProcessingThreshold; phy.m_linearDamp = bobj->damping; phy.m_angularDamp = bobj->rdamping; phy.m_mass = bobj->mass; phy.m_radius = bobj->inertia; phy.m_formFactor = bobj->formfactor; phy.m_margin = bobj->margin; if (bobj->type == OB_MESH) { Blender::Mesh* me = (Blender::Mesh*)bobj->data; if (me) { Blender::Material* ma = BlenderMaterial(bobj, 0); if (ma) { phy.m_restitution = ma->reflect; phy.m_friction = ma->friction; } } } if (phy.isRigidOrDynamic()) { switch (bobj->boundtype) { case OB_BOUND_BOX: phy.m_shape = SH_BOX; break; case OB_BOUND_SPHERE: phy.m_shape = SH_SPHERE; break; case OB_BOUND_CONE: phy.m_shape = SH_CONE; break; case OB_BOUND_CYLINDER: phy.m_shape = SH_CYLINDER; break; case OB_BOUND_POLYT: phy.m_shape = SH_CONVEX_TRIMESH; break; case OB_BOUND_POLYH: case OB_BOUND_DYN_MESH: phy.m_shape = SH_GIMPACT_MESH; break; } } else { if (bobj->type == OB_MESH) phy.m_shape = SH_BVH_MESH; else phy.m_shape = SH_SPHERE; } // setup velocity constraints if (phy.isRigidOrDynamic()) { if (phy.m_minVel > 0.f || phy.m_maxVel > 0.f) { gkLimitVelocityConstraint* vc = new gkLimitVelocityConstraint(); vc->setLimit(gkVector2(phy.m_minVel, phy.m_maxVel)); m_gscene->getConstraintManager()->addConstraint(gobj, vc); } } }
void gkBlenderMeshConverter::convert(void) { Blender::MFace* mface = m_bmesh->mface; Blender::MVert* mvert = m_bmesh->mvert; Blender::MCol* mcol = 0; Blender::MTFace* mtface[8] = {0, 0, 0, 0, 0, 0, 0, 0}; if (!mface || !mvert) return; Blender::MVert vpak[4]; unsigned int cpak[4]; unsigned int ipak[4]; int totlayer; gkSubMesh* curSubMesh = 0; utArray<gkMeshPair> meshtable; gkLoaderUtils_getLayers(m_bmesh, mtface, &mcol, totlayer); bool sortByMat = gkEngine::getSingleton().getUserDefs().blendermat; bool openglVertexColor = gkEngine::getSingleton().getUserDefs().rendersystem == OGRE_RS_GL; AssignmentListMap assignMap; bool canAssign = m_bmesh->dvert && m_bobj->parent && m_bobj->parent->type == OB_ARMATURE; if (canAssign) { int dgi = 0; for (Blender::bDeformGroup* dg = (Blender::bDeformGroup*)m_bobj->defbase.first; dg; dg = dg->next, ++dgi) { m_gmesh->createVertexGroup(dg->name); convertBoneAssignments(dgi, assignMap); } } for (int fi = 0; fi < m_bmesh->totface; fi++) { const Blender::MFace& curface = mface[fi]; // skip if face is not a triangle || quad if (!curface.v3) continue; const bool isQuad = curface.v4 != 0; TempFace t[2]; PackedFace f; f.totlay = totlayer; if (isQuad) { vpak[0] = mvert[curface.v1]; vpak[1] = mvert[curface.v2]; vpak[2] = mvert[curface.v3]; vpak[3] = mvert[curface.v4]; ipak[0] = curface.v1; ipak[1] = curface.v2; ipak[2] = curface.v3; ipak[3] = curface.v4; if (mcol != 0) { cpak[0] = packColour(mcol[0], openglVertexColor); cpak[1] = packColour(mcol[1], openglVertexColor); cpak[2] = packColour(mcol[2], openglVertexColor); cpak[3] = packColour(mcol[3], openglVertexColor); } else cpak[0] = cpak[1] = cpak[2] = cpak[3] = 0xFFFFFFFF; for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) { f.uvLayers[i][0] = gkVector2((float*)mtface[i][fi].uv[0]); f.uvLayers[i][1] = gkVector2((float*)mtface[i][fi].uv[1]); f.uvLayers[i][2] = gkVector2((float*)mtface[i][fi].uv[2]); f.uvLayers[i][3] = gkVector2((float*)mtface[i][fi].uv[3]); } } f.verts = vpak; f.index = ipak; f.colors = cpak; gkVector3 e0, e1; e0 = (gkVector3(mvert[curface.v1].co) - gkVector3(mvert[curface.v2].co)); e1 = (gkVector3(mvert[curface.v3].co) - gkVector3(mvert[curface.v4].co)); if (e0.squaredLength() < e1.squaredLength()) { convertIndexedTriangle(&t[0], 0, 1, 2, f); convertIndexedTriangle(&t[1], 2, 3, 0, f); } else { convertIndexedTriangle(&t[0], 0, 1, 3, f); convertIndexedTriangle(&t[1], 3, 1, 2, f); } } else { for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) { f.uvLayers[i][0] = gkVector2((float*)mtface[i][fi].uv[0]); f.uvLayers[i][1] = gkVector2((float*)mtface[i][fi].uv[1]); f.uvLayers[i][2] = gkVector2((float*)mtface[i][fi].uv[2]); } } vpak[0] = mvert[curface.v1]; vpak[1] = mvert[curface.v2]; vpak[2] = mvert[curface.v3]; ipak[0] = curface.v1; ipak[1] = curface.v2; ipak[2] = curface.v3; if (mcol != 0) { cpak[0] = packColour(mcol[0], openglVertexColor); cpak[1] = packColour(mcol[1], openglVertexColor); cpak[2] = packColour(mcol[2], openglVertexColor); } else cpak[0] = cpak[1] = cpak[2] = cpak[3] = 0xFFFFFFFF; f.verts = vpak; f.index = ipak; f.colors = cpak; convertIndexedTriangle(&t[0], 0, 1, 2, f); } gkMeshPair tester(curSubMesh); if (sortByMat) { int mode = 0; if (mtface[0]) mode = mtface[0][fi].mode; tester.test = gkMeshHashKey(curface.mat_nr, mode); } else { Blender::Image* ima[8] = {0, 0, 0, 0, 0, 0, 0, 0}; for (int i = 0; i < totlayer; i++) { if (mtface[i] != 0) ima[i] = mtface[i][fi].tpage; } int mode = 0, alpha = 0; if (mtface[0]) { mode = mtface[0][fi].mode; alpha = mtface[0][fi].transp; } tester.test = gkMeshHashKey(mode, alpha, ima); } // find submesh UTsize arpos = 0; if ((arpos = meshtable.find(tester)) == UT_NPOS) { curSubMesh = new gkSubMesh(); curSubMesh->setTotalLayers(totlayer); curSubMesh->setVertexColors(mcol != 0); m_gmesh->addSubMesh(curSubMesh); tester.item = curSubMesh; meshtable.push_back(tester); } else curSubMesh = meshtable.at(arpos).item; if (curSubMesh == 0) continue; if (!(curface.flag & ME_SMOOTH)) { // face normal calcNormal(&t[0]); if (isQuad) t[1].v0.no = t[1].v1.no = t[1].v2.no = t[0].v0.no; } int triflag = 0; if (mtface[0]) { if (mtface[0][fi].mode & TF_DYNAMIC) triflag |= gkTriangle::TRI_COLLIDER; if (mtface[0][fi].mode & TF_INVISIBLE) triflag |= gkTriangle::TRI_INVISIBLE; } else triflag = gkTriangle::TRI_COLLIDER; curSubMesh->addTriangle(t[0].v0, t[0].i0, t[0].v1, t[0].i1, t[0].v2, t[0].i2, triflag); if (isQuad) { curSubMesh->addTriangle(t[1].v0, t[1].i0, t[1].v1, t[1].i1, t[1].v2, t[1].i2, triflag); } if (mcol) mcol += 4; } // build materials utArrayIterator<utArray<gkMeshPair> > iter(meshtable); while (iter.hasMoreElements()) { gkMeshHashKey& key = iter.peekNext().test; gkSubMesh* val = iter.peekNext().item; Blender::Material* bmat = BlenderMaterial(m_bobj, key.m_matnr); if (key.m_blenderMat) { if (bmat) convertMaterial(bmat, val->getMaterial(), key); } else convertTextureFace(val->getMaterial(), key, (Blender::Image**)key.m_images); if (canAssign) { // build def groups assignBoneAssignments(val, assignMap); } iter.getNext(); } }