void gkAnimationLoader::convert25AnimData(gkGameObject* obj, Blender::AnimData* adt, gkScalar animfps) { if(!adt) return; if(adt->nla_tracks.first) { // TODO 2.5x NLA } if(adt->action) { gkResourceName name(GKB_IDNAME(adt->action), m_groupName); gkAnimation* act = dynamic_cast<gkAnimation*>(gkAnimationManager::getSingleton().getByName(name)); if(!act) { convertAction25(adt->action, animfps); act = dynamic_cast<gkAnimation*>(gkAnimationManager::getSingleton().getByName(name)); } if(act) { gkAnimationPlayer* play = obj->addAnimation(act, GKB_IDNAME(adt->action)); play->setWeight(adt->act_influence); } } }
gkAnimation* gkAnimationLoader::convertObjectIpoToAnimation(Blender::Ipo* bipo, gkScalar animfps) { gkResourceName name(GKB_IDNAME(bipo), m_groupName); gkAnimationManager& amgr = gkAnimationManager::getSingleton(); gkKeyedAnimation* act = amgr.createKeyedAnimation(name); gkScalar start, end; if(!act) return 0; gkObjectChannel* chan = new gkObjectChannel(GKB_IDNAME(bipo), act); act->addChannel(chan); getIPOStartEnd(bipo, start, end); convertObjectIpo(bipo, chan, start, end, animfps); // never quaternion for blender <2.4 chan->setEulerRotation(true); // apply time range act->setLength( (end-start)/animfps); return act; }
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::convertObjectGeneral(gkGameObject* gobj, Blender::Object* bobj) { gkQuaternion quat; gkVector3 loc, scale; gkMatrix4 obmat = gkMathUtils::getFromFloat(bobj->obmat); gkMathUtils::extractTransform(obmat, loc, quat, scale); // prevent zero scale gkVector3 scaleTest = gkVector3(bobj->size[0], bobj->size[1], bobj->size[2]); if (scaleTest.isZeroLength()) scale = gkVector3(1.f, 1.f, 1.f); gkGameObjectProperties& props = gobj->getProperties(); if (bobj->parent && validObject(bobj->parent)) { props.m_parent = GKB_IDNAME(bobj->parent); if ( bobj->parent->type==OB_ARMATURE){ gkString parentBoneName(bobj->parsubstr); if (!parentBoneName.empty()){ props.m_boneParent = parentBoneName; } } } props.m_transform = gkTransformState(loc, quat, scale); if (bobj->restrictflag & OB_RESTRICT_RENDER) props.m_mode |= GK_INVISIBLE; gobj->setActiveLayer((m_bscene->lay & bobj->lay) != 0); gobj->setLayer((UTuint32)bobj->lay); }
void gkBlenderSceneConverter::applyParents(utArray<Blender::Object*> &children) { UTsize i; for (i = 0; i < children.size(); i++) { Blender::Object* bchild = children.at(i); gkGameObject* gchild = m_gscene->getObject(GKB_IDNAME(bchild)); if (gchild) { gkGameObject* gpar = m_gscene->getObject(GKB_IDNAME(bchild->parent)); if (gpar && !gpar->getProperties().hasBoneParent()) gchild->setParent(gpar); } } }
void gkBlenderMeshConverter::convertTextureFace(gkMaterialProperties& gma, gkMeshHashKey& hk, Blender::Image** imas) { gma.m_mode = hk.m_mode; if (imas) { static char buf[32]; static int uid = 0; sprintf(buf, "TextureFace %i", (uid++)); gma.m_name = buf; } if (imas && gma.m_mode & gkMaterialProperties::MA_HASFACETEX) { gma.m_totaltex = 0; for (int i = 0; i < 8; i++) { if (imas[i] != 0) { Blender::Image* ima = imas[i]; gkTextureProperties& gte = gma.m_textures[gma.m_totaltex++]; gte.m_layer = i; gte.m_image = gte.m_name = GKB_IDNAME(ima); } } } }
void gkAnimationLoader::convertObject(gkGameObject* obj, Blender::Object* bobj, bool pre25compat, gkScalar animfps) { // 2.4x if(pre25compat) { if(bobj && bobj->ipo) { gkAnimation* act = dynamic_cast<gkAnimation*>(gkAnimationManager::getSingleton().getByName(gkResourceName(GKB_IDNAME(bobj->ipo), m_groupName))); if(!act) act = convertObjectIpoToAnimation(bobj->ipo, animfps); if(act) obj->addAnimation(act, GKB_IDNAME(bobj->ipo)); } if(bobj && bobj->action) { gkResourceName name(GKB_IDNAME(bobj->action), m_groupName); gkAnimation* act = dynamic_cast<gkAnimation*>(gkAnimationManager::getSingleton().getByName(name)); if(!act) { convertAction(bobj->action, pre25compat, animfps); act = dynamic_cast<gkAnimation*>(gkAnimationManager::getSingleton().getByName(name)); } if(act) obj->addAnimation(act, GKB_IDNAME(bobj->action)); } // TODO 2.4 NLA } // 2.5x else if (bobj->adt) { convert25AnimData(obj, bobj->adt, animfps); } // object data switch (bobj->type) { case OB_LAMP: convertLamp(obj, bobj, pre25compat, animfps); break; case OB_CAMERA: convertCamera(obj, bobj, pre25compat, animfps); break; case OB_MESH: convertMesh(obj, bobj, pre25compat, animfps); break; case OB_ARMATURE: convertArmature(obj, bobj, pre25compat, animfps); break; } }
// this have to be called after all scenes created their groups void gkBlenderSceneConverter::convertGroupInstances() { m_gscene = static_cast<gkScene*>(gkSceneManager::getSingleton().getByName(gkResourceName(GKB_IDNAME(m_bscene), m_groupName))); if (m_gscene) { gkGroupManager* mgr = gkGroupManager::getSingletonPtr(); utArray<Blender::Object*> groups; for (Blender::Base* base = (Blender::Base*)m_bscene->base.first; base; base = base->next) { if (!base->object) continue; Blender::Object* bobj = base->object; // non - conversion object if (!validObject(bobj)) continue; // only concentrate on the group-instances if ( (bobj->transflag & OB_DUPLIGROUP) && bobj->dup_group != 0) groups.push_back(bobj); } // Process user created groups. utArray<Blender::Object*>::Iterator it = groups.iterator(); while (it.hasMoreElements()) { Blender::Object* bobj = it.getNext(); // Should not fail GK_ASSERT((bobj->transflag& OB_DUPLIGROUP && bobj->dup_group != 0)); // Owning group Blender::Group* bgobj = bobj->dup_group; const gkResourceName groupName(GKB_IDNAME(bgobj), m_groupName); if (mgr->exists(groupName)) { gkGameObjectGroup* ggobj = (gkGameObjectGroup*)mgr->getByName(groupName); gkGameObjectInstance* inst = ggobj->createGroupInstance(m_gscene, gkResourceName(GKB_IDNAME(bobj), m_groupName),0,bobj->lay); inst->getRoot()->_makeGroup(ggobj); inst->getRoot()->_makeGroupInstance(inst); if (inst) convertObject(bobj, inst->getRoot()); } } } else { gkLogger::write("CAUTION:Calling gkBlenderSceneConverter::convertGroupInstance() without calling convert(false) before doesn't work! No group-instances created!",true); } }
void gkParticleConverter::convertParticle(Blender::ParticleSettings* pt) { if (!pt || !pt->effector_weights) return; if (pt->ren_as == PART_DRAW_NOT) return; Blender::EffectorWeights* wt = pt->effector_weights; gkParticleSettingsProperties pp; pp.m_phyType = pt->phystype; pp.m_name = GKB_IDNAME(pt); pp.m_emitfrom = pt->from; pp.m_amount = pt->totpart; pp.m_lifetime = pt->lifetime/m_fps; pp.m_start = pt->sta/m_fps; pp.m_end = pt->end/m_fps; pp.m_random = pt->randlife; pp.m_jitter = pt->jitfac; pp.m_velocity = gkVector3(pt->ob_vel[0], pt->ob_vel[1], pt->ob_vel[2])*10; pp.m_velNormal = pt->normfac; pp.m_velTanget = pt->tanfac; pp.m_size = pt->size*10; pp.m_mass = pt->mass; pp.m_sizeRandom = pt->randsize; pp.m_gravity = wt->global_gravity; pp.m_trailCount = pt->trail_count; pp.m_drawEmitter = (pt->draw & 0x8) != 0; pp.m_material = pt->omat - 1; if (pt->ren_as == PART_DRAW_HALO) pp.m_render = gkParticleSettingsProperties::R_HALO; else if (pt->ren_as == PART_DRAW_BB) pp.m_render = gkParticleSettingsProperties::R_BILLBOARD; else if (pt->ren_as == PART_DRAW_OB) pp.m_render = gkParticleSettingsProperties::R_OBJECT; else if (pt->ren_as == PART_DRAW_GR) pp.m_render = gkParticleSettingsProperties::R_GROUP; else if (pt->ren_as == PART_DRAW_LINE) pp.m_render = gkParticleSettingsProperties::R_LINE; else if (pt->ren_as == PART_DRAW_PATH) pp.m_render = gkParticleSettingsProperties::R_PATH; //else if (pt->ren_as == PART_DRAW_NOT) // pp.m_render = gkParticleSettingsProperties::R_NONE; gkParticleManager::getSingleton().createParticle(gkResourceName(pp.m_name, m_groupName), pp); }
void gkBlenderSceneConverter::convertWorld(void) { if (!m_gscene) return; gkSceneProperties& sprops = m_gscene->getProperties(); gkSceneMaterial& props = sprops.m_material; if (m_bscene->world) { Blender::World* world = m_bscene->world; sprops.m_gravity = gkVector3(0.f, 0.f, -world->gravity); props.m_ambient.r = world->ambr; props.m_ambient.g = world->ambg; props.m_ambient.b = world->ambb; props.m_horizon.r = world->horr; props.m_horizon.g = world->horg; props.m_horizon.b = world->horb; props.m_zenith.r = world->zenr; props.m_zenith.g = world->zeng; props.m_zenith.b = world->zenb; props.m_name = GKB_IDNAME(world); // take half far distance of the main camera props.m_distance = (m_bscene->camera && m_bscene->camera->type == OB_CAMERA ? ((Blender::Camera*)m_bscene->camera->data)->clipend * 0.5f : 10000.f); if ((world->skytype & WO_SKYBLEND) || (world->skytype & WO_SKYREAL)) { props.m_type = (world->skytype & WO_SKYBLEND) ? gkSceneMaterial::LINEAR : gkSceneMaterial::REFLECTED; } if (world->mode & WO_MIST) { sprops.m_fog.m_mode = world->mistype == 0 ? gkFogParams::FM_QUAD : world->mistype == 1 ? gkFogParams::FM_LIN : gkFogParams::FM_EXP; sprops.m_fog.m_start = world->miststa; sprops.m_fog.m_end = sprops.m_fog.m_start + world->mistdist; sprops.m_fog.m_intensity = world->misi; sprops.m_fog.m_color = props.m_horizon; if ((world->skytype & WO_SKYBLEND)) { gkVector3 a(world->horr, world->horg, world->horb), b(world->zenr, world->zeng, world->zenb); gkVector3 c = gkMathUtils::interp(a, b, 0.5); sprops.m_fog.m_color.r = c.x; sprops.m_fog.m_color.g = c.y; sprops.m_fog.m_color.b = c.z; } } } }
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::convertObject(Blender::Object* bobj, gkGameObject* gobj) { if (!m_gscene) return; GK_ASSERT(validObject(bobj)); if (gobj == 0) { gkHashedString name(GKB_IDNAME(bobj)); switch (bobj->type) { case OB_EMPTY: gobj = m_gscene->createObject(name); break; case OB_LAMP: gobj = m_gscene->createLight(name); break; case OB_CAMERA: gobj = m_gscene->createCamera(name); break; case OB_MESH: gobj = m_gscene->createEntity(name); break; case OB_ARMATURE: gobj = m_gscene->createSkeleton(name); break; case OB_CURVE: gobj = m_gscene->createCurve(name); break; } } // all game object property types if (gobj) { gkScalar animfps = m_bscene->r.frs_sec / m_bscene->r.frs_sec_base; convertObjectGeneral(gobj, bobj); convertObjectProperties(gobj, bobj); convertObjectPhysics(gobj, bobj); convertObjectConstraints(gobj, bobj); convertObjectLogic(gobj, bobj); convertObjectAnimations(gobj, bobj, animfps); // object data switch (bobj->type) { case OB_LAMP: convertObjectLamp(gobj, bobj); break; case OB_CAMERA: convertObjectCamera(gobj, bobj); break; case OB_MESH: convertObjectMesh(gobj, bobj); break; case OB_ARMATURE: convertObjectArmature(gobj, bobj); break; case OB_CURVE: convertObjectCurve(gobj, bobj); break; } convertObjectParticles(gobj, bobj); //need mesh info } }
void gkBlenderSceneConverter::convertObjectGroup(gkGameObjectGroup* gobj, Blender::Object* bobj) { if (!bobj) return; for (Blender::GroupObject* group = (Blender::GroupObject*)bobj->dup_group->gobject.first; group; group = (Blender::GroupObject*)group->next) { Blender::Object* gob = group->ob; if ( (gob->transflag & OB_DUPLIGROUP) && gob->dup_group != 0) convertObjectGroup(gobj, gob); else { gkGameObject* oth = m_gscene->getObject(GKB_IDNAME(gob)); if (oth) gobj->addObject(oth); } } }
void gkBlenderSceneConverter::convertGroups() { gkGroupManager* mgr = gkGroupManager::getSingletonPtr(); // This is a complete list of groups & containing objects. // The gkGameObjectGroup is a containter, the gkGameObjectGroupInstance // is where the object should be added / removed from the scene. // for (Blender::Group* bgrp = (Blender::Group*)m_file->_getInternalFile()->m_group.first; bgrp != 0; // bgrp = (Blender::Group*)bgrp->id.next) gkBlendListIterator iter = m_file->_getInternalFile()->getGroupList(); while (iter.hasMoreElements()) { Blender::Group* bgrp = (Blender::Group*)iter.getNext(); const gkResourceName groupName(GKB_IDNAME(bgrp), m_groupName); if (mgr->exists(groupName)) { // Can most likely assert here continue; } gkGameObjectGroup* group = (gkGameObjectGroup*)mgr->create(groupName); for (Blender::GroupObject* bgobj = (Blender::GroupObject*)bgrp->gobject.first; bgobj; bgobj = bgobj->next) { if (bgobj->ob) { Blender::Object* bobj = bgobj->ob; if (!validObject(bobj)) continue; // is object a group-instance? if ( (bobj->transflag& OB_DUPLIGROUP) && bobj->dup_group != 0) { gkGameObject* gobj = m_gscene->createObject(gkString(GKB_IDNAME(bobj))+"_grproot"); convertObject(bobj,gobj); // Owning group Blender::Group* bgobj = bobj->dup_group; const gkString instGroupName(GKB_IDNAME(bgobj)); if (gobj) group->addGroup(instGroupName,gobj); } else { gkGameObject* gobj = m_gscene->getObject(GKB_IDNAME(bobj)); // add it to the list if (gobj) group->addObject(gobj); } } } // Destroy if empty if (group->isEmpty()) mgr->destroy(group); else mgr->attachGroupToScene(m_gscene, group); } }
void gkBlenderSceneConverter::convert(bool createGroupInstances) { if (m_gscene) return; m_gscene = (gkScene*)gkSceneManager::getSingleton().create(gkResourceName(GKB_IDNAME(m_bscene), m_groupName)); if (!m_gscene) { gkPrintf("SceneConverter: duplicate scene '%s'\n", (m_bscene->id.name + 2)); return; } m_gscene->setLoadBlendFile(m_file); if (m_bscene->world) convertWorld(); convertSoundScene(); m_gscene->setLayer((UTuint32)m_bscene->lay); utArray<Blender::Object*> groups, armatureLinker; for (Blender::Base* base = (Blender::Base*)m_bscene->base.first; base; base = base->next) { if (!base->object) continue; Blender::Object* bobj = base->object; // non - conversion object if (!validObject(bobj)) continue; if ((bobj->transflag& OB_DUPLIGROUP) && bobj->dup_group != 0) groups.push_back(bobj); else convertObject(bobj); if (bobj->type == OB_MESH && bobj->parent != 0 && bobj->parent->type == OB_ARMATURE) armatureLinker.push_back(bobj); #if 0 if (bobj->parent) { short parentType = bobj->parent->type; short parentParType = bobj->parent->partype; } short parType = bobj->partype; int i=0; #endif } // build group instances convertGroups(); if (createGroupInstances) convertGroupInstances(); if (!armatureLinker.empty()) { gkMeshManager& memgr = gkMeshManager::getSingleton(); gkSkeletonManager& skmgr = gkSkeletonManager::getSingleton(); gkGameObjectManager& gomgr = gkGameObjectManager::getSingleton(); UTsize i; for (i = 0; i < armatureLinker.size(); ++i) { Blender::Object* obMe = armatureLinker[i]; Blender::Object* obAr = obMe->parent; gkEntity* gobjEn = gomgr.getEntity(GKB_IDNAME(obMe)); gkSkeleton* gobjSk = gomgr.getSkeleton(GKB_IDNAME(obAr)); if (gobjEn && gobjSk && !gobjEn->getProperties().hasBoneParent()) { gobjEn->setSkeleton(gobjSk); // Link data Blender::Mesh* me = static_cast<Blender::Mesh*>(obMe->data); Blender::bArmature* ar = static_cast<Blender::bArmature*>(obAr->data); if (memgr.exists(GKB_IDNAME(me)) && skmgr.exists(GKB_IDNAME(obAr))) { gkSkeletonResource* skel = skmgr.getByName<gkSkeletonResource>(GKB_IDNAME(obAr)); memgr.getByName<gkMesh>(GKB_IDNAME(me))->_setSkeleton(skel); gkBone::BoneList::Iterator roots = skel->getRootBoneList().iterator(); while (roots.hasMoreElements()) { gkBone* bone = roots.getNext(); gkMatrix4 eobmat = gkMathUtils::getFromFloat(obMe->obmat); gkMatrix4 sobmat = gkMathUtils::getFromFloat(obAr->obmat); gkTransformState trans(eobmat.inverse() * sobmat); if (!trans.isNaN()) bone->applyRootTransform(trans); else gkPrintf("Warning: Invalid bone transform."); } } } } } m_logic->resolveLinks(); }
void gkAnimationLoader::convertAction24(Blender::bAction* action, gkScalar animfps) { // 2.4x actions are always Pose actions gkKeyedAnimation* act = gkAnimationManager::getSingleton().createKeyedAnimation(gkResourceName(GKB_IDNAME(action), m_groupName)); if(!act) return; // min/max gkScalar start, end; get24ActionStartEnd(action, start, end); Blender::bActionChannel* bac = (Blender::bActionChannel*)action->chanbase.first; while (bac) { gkBoneChannel* chan = new gkBoneChannel(bac->name, act); act->addChannel(chan); if (bac->ipo) convertActionIpo(bac->ipo, chan, start, animfps); bac = bac->next; } // apply time range act->setLength( (end-start)/animfps); }
void gkBlenderSceneConverter::convertObjectConstraints(gkGameObject* gobj, Blender::Object* bobj) { // TODO: add more constraints gkConstraintManager* mgr = m_gscene->getConstraintManager(); for (Blender::bConstraint* bc = (Blender::bConstraint*)bobj->constraints.first; bc; bc = bc->next) { if (bc->type == CONSTRAINT_TYPE_RIGIDBODYJOINT) { Blender::bRigidBodyJointConstraint* jc = (Blender::bRigidBodyJointConstraint*)bc->data; gkPhysicsConstraintProperties p; p.m_target = GKB_IDNAME(jc->tar); p.m_axis = gkVector3(jc->axX, jc->axY, jc->axZ); p.m_pivot = gkVector3(jc->pivX, jc->pivY, jc->pivZ); for (int i = 0; i < 6; i++) { p.m_minLimit[i] = jc->minLimit[i]; p.m_maxLimit[i] = jc->maxLimit[i]; } p.m_flag = jc->flag; p.m_disableLinkedCollision = (jc->flag & CONSTRAINT_DISABLE_LINKED_COLLISION) != 0; if (jc->type == CONSTRAINT_RB_BALL) p.m_type = GK_BALL_CONSTRAINT; else if (jc->type == CONSTRAINT_RB_HINGE) p.m_type = GK_HINGE_CONSTRAINT; else if (jc->type == CONSTRAINT_RB_CONETWIST) p.m_type = GK_CONETWIST_CONSTRAINT; else if (jc->type == CONSTRAINT_RB_VEHICLE) p.m_type = GK_VEHICLE_CONSTRAINT; else if (jc->type == CONSTRAINT_RB_GENERIC6DOF) p.m_type = GK_D6_CONSTRAINT; gobj->getProperties().m_physics.m_constraints.push_back(p); } else { if (bc->enforce == 0.0) continue; gkConstraint* co = 0; if (bc->type == CONSTRAINT_TYPE_ROTLIMIT) { // rotation is in radians. Blender::bRotLimitConstraint* lr = (Blender::bRotLimitConstraint*)bc->data; if (!lr->flag) continue; gkLimitRotConstraint* c = new gkLimitRotConstraint(); co = c; if (lr->flag & LIMIT_XROT) c->setLimitX(gkVector2(lr->xmin * gkDPR, lr->xmax * gkDPR)); if (lr->flag & LIMIT_YROT) c->setLimitY(gkVector2(lr->ymin * gkDPR, lr->ymax * gkDPR)); if (lr->flag & LIMIT_ZROT) c->setLimitZ(gkVector2(lr->zmin * gkDPR, lr->zmax * gkDPR)); } else if (bc->type == CONSTRAINT_TYPE_LOCLIMIT) { Blender::bLocLimitConstraint* ll = (Blender::bLocLimitConstraint*)bc->data; if (!ll->flag) continue; gkLimitLocConstraint* c = new gkLimitLocConstraint(); co = c; if (ll->flag & LIMIT_XMIN) c->setMinX(ll->xmin); if (ll->flag & LIMIT_XMAX) c->setMaxX(ll->xmax); if (ll->flag & LIMIT_YMIN) c->setMinY(ll->ymin); if (ll->flag & LIMIT_YMAX) c->setMaxY(ll->ymax); if (ll->flag & LIMIT_ZMIN) c->setMinZ(ll->zmin); if (ll->flag & LIMIT_ZMAX) c->setMaxZ(ll->zmax); } if (co) { co->setSpace(bc->ownspace == CONSTRAINT_SPACE_LOCAL ? TRANSFORM_LOCAL : TRANSFORM_WORLD); co->setInfluence(bc->enforce); mgr->addConstraint(gobj, co); } } } }
void gkAnimationLoader::convertAction25(Blender::bAction* action, gkScalar animfps) { gkKeyedAnimation* act = gkAnimationManager::getSingleton().createKeyedAnimation(gkResourceName(GKB_IDNAME(action), m_groupName)); if(!act) return; // min/max gkScalar start, end; get25ActionStartEnd(action, start, end); Blender::FCurve* bfc = (Blender::FCurve*)action->curves.first; while (bfc) { utString rnap (bfc->rna_path); utString chan_name; utString transform_name; akAnimationChannel* chan; // Pose action if (rnap.substr(0, 10) == "pose.bones") { // TODO use regex? size_t i = rnap.rfind('\"'); chan_name = rnap.substr(12, i - 12); transform_name = rnap.substr(i + 3, rnap.length() - i + 3); chan = act->getChannel(chan_name); if(!chan) { chan = new gkBoneChannel(chan_name, act); act->addChannel(chan); } } // Object action else { transform_name = rnap; chan_name = "GKMainObjectChannel"; chan = act->getChannel(chan_name); if(!chan) { gkObjectChannel* ochan = new gkObjectChannel(chan_name, act); ochan->setEulerRotation(true); chan = static_cast<akAnimationChannel*>(ochan); act->addChannel(chan); } } if (bfc->bezt) { int code = -1; if (transform_name == "rotation_quaternion") { if (bfc->array_index == 0) code = gkTransformChannel::SC_ROT_QUAT_W; else if (bfc->array_index == 1) code = gkTransformChannel::SC_ROT_QUAT_X; else if (bfc->array_index == 2) code = gkTransformChannel::SC_ROT_QUAT_Y; else if (bfc->array_index == 3) code = gkTransformChannel::SC_ROT_QUAT_Z; } else if (transform_name == "rotation_euler") { if (bfc->array_index == 0) code = gkTransformChannel::SC_ROT_EULER_X; else if (bfc->array_index == 1) code = gkTransformChannel::SC_ROT_EULER_Y; else if (bfc->array_index == 2) code = gkTransformChannel::SC_ROT_EULER_Z; } else if (transform_name == "location") { if (bfc->array_index == 0) code = gkTransformChannel::SC_LOC_X; else if (bfc->array_index == 1) code = gkTransformChannel::SC_LOC_Y; else if (bfc->array_index == 2) code = gkTransformChannel::SC_LOC_Z; } else if (transform_name == "scale") { if (bfc->array_index == 0) code = gkTransformChannel::SC_SCL_X; else if (bfc->array_index == 1) code = gkTransformChannel::SC_SCL_Y; else if (bfc->array_index == 2) code = gkTransformChannel::SC_SCL_Z; } // ignore any other codes if (code != -1 && bfc->totvert > 0) ConvertSpline(bfc->bezt, chan, code, bfc->bezt->ipo, bfc->totvert, -start, 1.0f/animfps, 0, 1); } if (bfc->next == 0 || bfc->next->prev != bfc) break; //FIX: Momo_WalkBack fcurve is broken in uncompressed 256a. bfc = bfc->next; } // apply time range act->setLength( (end-start)/animfps); }
void gkBlenderSceneConverter::convertGroups(utArray<Blender::Object*> &groups) { gkGroupManager* mgr = gkGroupManager::getSingletonPtr(); // This is a complete list of groups & containing objects. // The gkGameObjectGroup is a containter, the gkGameObjectGroupInstance // is where the object should be added / removed from the scene. // for (Blender::Group* bgrp = (Blender::Group*)m_file->_getInternalFile()->m_group.first; bgrp != 0; // bgrp = (Blender::Group*)bgrp->id.next) gkBlendListIterator iter = m_file->_getInternalFile()->getGroupList(); while (iter.hasMoreElements()) { Blender::Group* bgrp = (Blender::Group*)iter.getNext(); const gkResourceName groupName(GKB_IDNAME(bgrp), m_groupName); if (mgr->exists(groupName)) { // Can most likely assert here continue; } gkGameObjectGroup* group = (gkGameObjectGroup*)mgr->create(groupName); for (Blender::GroupObject* bgobj = (Blender::GroupObject*)bgrp->gobject.first; bgobj; bgobj = bgobj->next) { if (bgobj->ob) { Blender::Object* bobj = bgobj->ob; if (!validObject(bobj)) continue; gkGameObject* gobj = m_gscene->getObject(GKB_IDNAME(bobj)); // add it to the list if (gobj) group->addObject(gobj); } } // Destroy if empty if (group->isEmpty()) mgr->destroy(group); else mgr->attachGroupToScene(m_gscene, group); } // Process user created groups. utArray<Blender::Object*>::Iterator it = groups.iterator(); while (it.hasMoreElements()) { Blender::Object* bobj = it.getNext(); // Should not fail GK_ASSERT((bobj->transflag& OB_DUPLIGROUP && bobj->dup_group != 0)); // Owning group Blender::Group* bgobj = bobj->dup_group; const gkResourceName groupName(GKB_IDNAME(bgobj), m_groupName); if (mgr->exists(groupName)) { gkGameObjectGroup* ggobj = (gkGameObjectGroup*)mgr->getByName(groupName); gkGameObjectInstance* inst = ggobj->createGroupInstance(m_gscene, gkResourceName(GKB_IDNAME(bobj), m_groupName)); if (inst) convertObject(bobj, inst->getRoot()); } } }
void gkBlenderMeshConverter::convertMaterial(Blender::Material* bma, gkMaterialProperties& gma, gkMeshHashKey& hk) { convertTextureFace(gma, hk, 0); gma.m_name = GKB_IDNAME(bma); gma.m_hardness = bma->har / 4.f; gma.m_refraction = bma->ref; gma.m_emissive = bma->emit; gma.m_ambient = bma->amb; gma.m_spec = bma->spec; gma.m_alpha = bma->alpha; gma.m_diffuse = gkColor(bma->r, bma->g, bma->b); gma.m_specular = gkColor(bma->specr, bma->specg, bma->specb); gma.m_rblend = getRampBlendType(bma->rampblend_col); if (bma->mode & MA_ZTRA) gma.m_mode |= gkMaterialProperties::MA_DEPTHWRITE; if (bma->mode & MA_SHADOW) gma.m_mode |= gkMaterialProperties::MA_RECEIVESHADOWS; if (bma->mode & MA_WIRE) gma.m_mode |= gkMaterialProperties::MA_WIREFRAME; if (!(bma->mode & MA_SHLESS)) gma.m_mode |= gkMaterialProperties::MA_LIGHTINGENABLED; // TODO: this need to be checked, as there are cases where material-alpha is set to zero to give the texture-alpha full control if (bma->alpha <= 0.f) gma.m_mode |= gkMaterialProperties::MA_INVISIBLE; if (bma->mode & MA_RAMP_COL) gma.m_mode |= gkMaterialProperties::MA_HASRAMPBLEND; if (!(bma->game.flag & GEMAT_BACKCULL)) gma.m_mode |= gkMaterialProperties::MA_TWOSIDE; if (bma->game.flag & GEMAT_INVISIBLE) gma.m_mode |= gkMaterialProperties::MA_INVISIBLE; if (bma->game.alpha_blend & GEMAT_ALPHA) gma.m_mode |= gkMaterialProperties::MA_ALPHABLEND; if (bma->game.alpha_blend & GEMAT_CLIP) gma.m_mode |= gkMaterialProperties::MA_ALPHACLIP; // textures if (bma->mtex != 0) { gma.m_totaltex = 0; for (int i = 0; i < MAX_MTEX; i++) { if (!bma->mtex[i] || !bma->mtex[i]->tex) continue; if (bma->mtex[i]->tex->type == TEX_IMAGE) { Blender::MTex* mtex = bma->mtex[i]; Blender::Image* ima = mtex->tex->ima; if (!ima) continue; gkTextureProperties& gte = gma.m_textures[gma.m_totaltex++]; gte.m_image = gte.m_name = GKB_IDNAME(ima); if (mtex->texflag & MTEX_STENCIL) { gte.m_mode |= gkTextureProperties::TM_SPLAT; gte.m_texmode |= gkTextureProperties::TX_STENCIL; } if (mtex->texflag & MTEX_NEGATIVE) gte.m_texmode |= gkTextureProperties::TX_NEGATIVE; if (mtex->texflag & MTEX_RGBTOINT) gte.m_texmode |= gkTextureProperties::TX_RGBTOINTEN; if (mtex->mapto & MAP_ALPHA) { gte.m_mode |= gkTextureProperties::TM_ALPHA; gma.m_mode |= gkMaterialProperties::MA_ALPHABLEND; } if ((mtex->mapto & MAP_NORM) || (mtex->maptoneg & MAP_NORM)) { gte.m_mode |= gkTextureProperties::TM_NORMAL; gma.m_tangentLayer = i; } if ((mtex->mapto & MAP_SPEC) || (mtex->maptoneg & MAP_SPEC)) gte.m_mode |= gkTextureProperties::TM_SPECULAR; if ((mtex->mapto & MAP_REF) || (mtex->maptoneg & MAP_REF)) gte.m_mode |= gkTextureProperties::TM_REFRACTION; if ((mtex->mapto & MAP_EMIT) || (mtex->maptoneg & MAP_EMIT)) gte.m_mode |= gkTextureProperties::TM_EMMISIVE; if (mtex->normapspace == MTEX_NSPACE_OBJECT) //else set to tagent space. gte.m_texmode |= gkTextureProperties::TX_OBJ_SPACE; gte.m_blend = getTexBlendType(mtex->blendtype); gte.m_layer = findTextureLayer(mtex); gte.m_mix = mtex->colfac; gte.m_normalFactor = mtex->norfac; gte.m_diffuseColorFactor = mtex->colfac; gte.m_diffuseAlpahFactor = mtex->alphafac; gte.m_speculaColorFactor = mtex->colspecfac; gte.m_speculaHardFactor = mtex->hardfac; gte.m_scale.x = 1/mtex->size[0]; gte.m_scale.y = 1/mtex->size[1]; gte.m_scale.z = 1/mtex->size[2]; } } } }
void gkAnimationLoader::convertAction25(Blender::bAction* action, gkScalar animfps) { gkKeyedAnimation* act = gkAnimationManager::getSingleton().createKeyedAnimation(gkResourceName(GKB_IDNAME(action), m_groupName)); if(!act) return; // min/max gkScalar start, end; get25ActionStartEnd(action, start, end); Blender::FCurve* bfc = (Blender::FCurve*)action->curves.first; while (bfc) { utString rnap (bfc->rna_path); utString chan_name; utString transform_name; printf("rnap = %s \n",rnap.c_str()); akAnimationChannel* chan; // Pose action if (rnap.substr(0, 10) == "pose.bones") { // TODO use regex? size_t i = rnap.rfind('\"'); chan_name = rnap.substr(12, i - 12); transform_name = rnap.substr(i + 3, rnap.length() - i + 3); chan = act->getChannel(chan_name); if(!chan) { chan = new gkBoneChannel(chan_name, act); act->addChannel(chan); } } // Object action else { transform_name = rnap; chan_name = "GKMainObjectChannel"; chan = act->getChannel(chan_name); if(!chan) { gkObjectChannel* ochan = new gkObjectChannel(chan_name, act); ochan->setEulerRotation(true); chan = static_cast<akAnimationChannel*>(ochan); act->addChannel(chan); } } if (bfc->bezt) { int code = -1; if (transform_name == "rotation_quaternion") { if (bfc->array_index == 0) code = gkTransformChannel::SC_ROT_QUAT_W; else if (bfc->array_index == 1) code = gkTransformChannel::SC_ROT_QUAT_X; else if (bfc->array_index == 2) code = gkTransformChannel::SC_ROT_QUAT_Y; else if (bfc->array_index == 3) code = gkTransformChannel::SC_ROT_QUAT_Z; } else if (transform_name == "rotation_euler") { if (bfc->array_index == 0) code = gkTransformChannel::SC_ROT_EULER_X; else if (bfc->array_index == 1) code = gkTransformChannel::SC_ROT_EULER_Y; else if (bfc->array_index == 2) code = gkTransformChannel::SC_ROT_EULER_Z; } else if (transform_name == "location") { if (bfc->array_index == 0) code = gkTransformChannel::SC_LOC_X; else if (bfc->array_index == 1) code = gkTransformChannel::SC_LOC_Y; else if (bfc->array_index == 2) code = gkTransformChannel::SC_LOC_Z; } else if (transform_name == "scale") { if (bfc->array_index == 0) code = gkTransformChannel::SC_SCL_X; else if (bfc->array_index == 1) code = gkTransformChannel::SC_SCL_Y; else if (bfc->array_index == 2) code = gkTransformChannel::SC_SCL_Z; } //add channel zy else if (transform_name == "alpha") { code = gkTransformChannel::SC_ALPHA; }else if(transform_name == "diffuse_color") { if (bfc->array_index == 0) code = gkTransformChannel::SC_DIFFUSE_COLOR_R; else if (bfc->array_index == 1) code = gkTransformChannel::SC_DIFFUSE_COLOR_G; else if (bfc->array_index == 2) code = gkTransformChannel::SC_DIFFUSE_COLOR_B; }else if(transform_name == "texture_slots[0].offset") { if (bfc->array_index == 0) code = gkTransformChannel::SC_TEXTURE0_OFFSET_X; else if (bfc->array_index == 1) code = gkTransformChannel::SC_TEXTURE0_OFFSET_Y; else if (bfc->array_index == 2) code = gkTransformChannel::SC_TEXTURE0_OFFSET_Z; } else if(transform_name == "texture_slots[1].offset") { if (bfc->array_index == 0) code = gkTransformChannel::SC_TEXTURE1_OFFSET_X; else if (bfc->array_index == 1) code = gkTransformChannel::SC_TEXTURE1_OFFSET_Y; else if (bfc->array_index == 2) code = gkTransformChannel::SC_TEXTURE1_OFFSET_Z; } else if(transform_name == "image_user.frame_duration") { code = gkTransformChannel::SC_IMAGE_FRAME; }else if(transform_name == "texture_slots[0].alpha_factor") { code = gkTransformChannel::SC_TEXTURE0_ALPHA_FACTOR; }else if(transform_name == "texture_slots[1].alpha_factor") { code = gkTransformChannel::SC_TEXTURE1_ALPHA_FACTOR; }else if(transform_name == "texture_slots[0].diffuse_color_factor") { code = gkTransformChannel::SC_TEXTURE0_DIFFUSE_COLOR_FACTOR; } else if(transform_name == "texture_slots[1].diffuse_color_factor") { code = gkTransformChannel::SC_TEXTURE1_DIFFUSE_COLOR_FACTOR; } else { gkPrintf("Not supported animation format"); } // ignore any other codes if (code != -1 && bfc->totvert > 0) ConvertSpline(bfc->bezt, chan, code, bfc->bezt->ipo, bfc->totvert, -start, 1.0f/animfps, 0, 1); } if (bfc->next == 0 || bfc->next->prev != bfc) break; //FIX: Momo_WalkBack fcurve is broken in uncompressed 256a. bfc = bfc->next; } // apply time range act->setLength( (end-start)/animfps); act->setStartFrame(start); act->setEndFrame(end); }