[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21918] branches/soc-2009-chingachgook/ source/blender/collada/DocumentImporter.cpp: COLLADA importer:
Arystanbek Dyussenov
arystan.d at gmail.com
Sun Jul 26 11:29:26 CEST 2009
Revision: 21918
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21918
Author: kazanbas
Date: 2009-07-26 11:29:25 +0200 (Sun, 26 Jul 2009)
Log Message:
-----------
COLLADA importer:
- splitted code into separate classes: ArmatureImporter, MeshImporter
- commented out texture-to-mesh binding code which was difficult to comprehend, Chingiz will re-think/re-write
Modified Paths:
--------------
branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp
Modified: branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp
===================================================================
--- branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp 2009-07-26 09:28:33 UTC (rev 21917)
+++ branches/soc-2009-chingachgook/source/blender/collada/DocumentImporter.cpp 2009-07-26 09:29:25 UTC (rev 21918)
@@ -121,55 +121,46 @@
return "UNKNOWN";
}
-/*
+class UnitConverter
+{
+private:
+ COLLADAFW::FileInfo::Unit unit;
+ COLLADAFW::FileInfo::UpAxisType up_axis;
- COLLADA Importer limitations:
+public:
- - no multiple scene import, all objects are added to active scene
+ UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) {}
- */
-/** Class that needs to be implemented by a writer.
- IMPORTANT: The write functions are called in arbitrary order.*/
-class Writer: public COLLADAFW::IWriter
+ void read_asset(const COLLADAFW::FileInfo* asset)
+ {
+ }
+
+ // TODO
+ // convert vector vec from COLLADA format to Blender
+ void convertVec3(float *vec)
+ {
+ }
+
+ // TODO need also for angle conversion, time conversion...
+
+ void mat4_from_dae_mat4(float out[][4], const COLLADABU::Math::Matrix4& in) {
+ // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h)
+ // so here, to make a blender matrix, we simply swap columns and rows
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ out[i][j] = in[j][i];
+ }
+ }
+ }
+};
+
+class ArmatureImporter
{
private:
- std::string mFilename;
-
- bContext *mContext;
+ Scene *scene;
+ UnitConverter *unit_converter;
- std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
- std::map<COLLADAFW::UniqueId, Image*> uid_image_map;
- std::map<COLLADAFW::UniqueId, Material*> uid_material_map;
- std::map<COLLADAFW::UniqueId, Material*> uid_effect_map;
- std::map<COLLADAFW::UniqueId, Camera*> uid_camera_map;
- std::map<COLLADAFW::UniqueId, Lamp*> uid_lamp_map;
- std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> skinid_meshid_map;
- // maps for assigning textures to uv layers
- //std::map<COLLADAFW::TextureMapId, char*> set_layername_map;
- std::map<COLLADAFW::TextureMapId, std::vector<MTex*> > index_mtex_map;
- // this structure is used to assign material indices to faces
- // when materials are assigned to an object
- struct Primitive {
- MFace *mface;
- unsigned int totface;
- };
- typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
- // amazing name!
- std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map;
- // maps for animation
- std::map<COLLADAFW::UniqueId, std::vector<FCurve*> > uid_fcurve_map;
- struct AnimatedTransform {
- Object *ob;
- // COLLADAFW::Node *node;
- COLLADAFW::Transformation *tm; // which transform is animated by an AnimationList->id
- };
- // Nodes don't share AnimationLists (Arystan)
- std::map<COLLADAFW::UniqueId, AnimatedTransform> uid_animated_map; // AnimationList->uniqueId to AnimatedObject map
-
- // ----------------------------------------------------------------------
- // Armature and related
-
- // to build armature bones form inverse bind matrices
+ // to build armature bones from inverse bind matrices
struct JointData {
float inv_bind_mat[4][4]; // joint inverse bind matrix
Object *ob_arm; // armature object
@@ -177,34 +168,202 @@
std::map<int, JointData> joint_index_to_joint_info_map;
std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map;
+ /*
struct ArmatureData {
bArmature *arm;
COLLADAFW::SkinController *controller;
};
std::map<COLLADAFW::UniqueId, ArmatureData> controller_id_to_arm_info_map;
+ */
std::vector<COLLADAFW::Node*> root_joints;
+ std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> controller_id_to_geom_id_map;
- class UnitConverter
+ JointData *get_joint_data(COLLADAFW::Node *node)
{
- private:
- COLLADAFW::FileInfo::Unit mUnit;
- COLLADAFW::FileInfo::UpAxisType mUpAxis;
- public:
- UnitConverter(COLLADAFW::FileInfo::UpAxisType upAxis, COLLADAFW::FileInfo::Unit& unit) :
- mUpAxis(upAxis), mUnit(unit)
- {
+ const COLLADAFW::UniqueId& joint_id = node->getUniqueId();
+
+ if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) {
+ fprintf(stderr, "Cannot find a joint index by joint id for %s.\n",
+ node->getOriginalId().c_str());
+ return NULL;
}
- // TODO
- // convert vector vec from COLLADA format to Blender
- void convertVec3(float *vec)
- {
+ int joint_index = joint_id_to_joint_index_map[joint_id];
+
+ return &joint_index_to_joint_info_map[joint_index];
+ }
+
+ void create_bone(COLLADAFW::Node *node, EditBone *parent, bArmature *arm)
+ {
+ JointData* jd = get_joint_data(node);
+
+ if (jd) {
+ float mat[4][4];
+
+ // get original world-space matrix
+ Mat4Invert(mat, jd->inv_bind_mat);
+
+ // TODO rename from Node "name" attrs later
+ EditBone *bone = addEditBone(arm, "Bone");
+
+ if (parent) bone->parent = parent;
+
+ // set head
+ VecCopyf(bone->head, mat[3]);
+
+ // set tail, can't set it to head because 0-length bones are not allowed
+ float vec[3] = {0.0f, 0.5f, 0.0f};
+ VecAddf(bone->tail, bone->head, vec);
+
+ // set parent tail
+ if (parent)
+ VecCopyf(parent->tail, bone->head);
+
+ COLLADAFW::NodePointerArray& children = node->getChildNodes();
+ for (int i = 0; i < children.getCount(); i++) {
+ create_bone(children[i], bone, arm);
+ }
}
+ }
+
+ void create_bone_branch(COLLADAFW::Node *root)
+ {
+ JointData* jd = get_joint_data(root);
+ if (!jd) return;
+
+ Object *ob_arm = jd->ob_arm;
- // TODO need also for angle conversion, time conversion...
+ // enter armature edit mode
+ ED_armature_to_edit(ob_arm);
+
+ COLLADAFW::NodePointerArray& children = root->getChildNodes();
+ for (int i = 0; i < children.getCount(); i++) {
+ create_bone(children[i], NULL, (bArmature*)ob_arm->data);
+ }
+
+ // exit armature edit mode
+ ED_armature_from_edit(scene, ob_arm);
+ }
+
+public:
+
+ ArmatureImporter(UnitConverter *conv, Scene *sce) : unit_converter(conv), scene(sce) {}
+
+ void add_root_joint(COLLADAFW::Node *node)
+ {
+ root_joints.push_back(node);
+ }
+
+ bool has_root_joints()
+ {
+ return root_joints.size() > 0;
+ }
+
+ // here we add bones to armature, having armatures previously created in write_controller
+ void build_armatures()
+ {
+ this->scene = scene;
+ std::vector<COLLADAFW::Node*>::iterator it;
+ for (it = root_joints.begin(); it != root_joints.end(); it++) {
+ create_bone_branch(*it);
+ }
+ }
+
+ bool write_skin_controller_data(const COLLADAFW::SkinControllerData* skin)
+ {
+ // use inverse bind matrices to construct armature
+ // it is safe to invert them to get the original matrices
+ // because if they are inverse matrices, they can be inverted
+
+ // just do like so:
+ // - create armature
+ // - enter editmode
+ // - add edit bones and head/tail properties using matrices and parent-child info
+ // - exit edit mode
+
+ // store join inv bind matrix to use it later in armature construction
+ const COLLADAFW::Matrix4Array& inv_bind_mats = skin->getInverseBindMatrices();
+ int i;
+ for (i = 0; i < skin->getJointsCount(); i++) {
+ JointData jd;
+ unit_converter->mat4_from_dae_mat4(jd.inv_bind_mat, inv_bind_mats[i]);
+ joint_index_to_joint_info_map[i] = jd;
+ }
+
+ return true;
+ }
+
+ bool write_controller(const COLLADAFW::Controller* controller)
+ {
+ // here we:
+ // - create armature
+ // - create EditBones, not setting parent-child relationships
+ // - store armature
+
+ const COLLADAFW::UniqueId& skin_id = controller->getUniqueId();
+
+ if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) {
+
+ Object *ob_arm = add_object(this->scene, OB_ARMATURE);
+
+ COLLADAFW::SkinController *skinco = (COLLADAFW::SkinController*)controller;
+ const COLLADAFW::UniqueId& id = skinco->getSkinControllerData();
+
+ // to find geom id by controller id
+ this->controller_id_to_geom_id_map[skin_id] = skinco->getSource();
+
+ // "Node" ids
+ const COLLADAFW::UniqueIdArray& joint_ids = skinco->getJoints();
+
+ int i;
+ for (i = 0; i < joint_ids.getCount(); i++) {
+
+ // store armature pointer
+ JointData& jd = joint_index_to_joint_info_map[i];
+ jd.ob_arm = ob_arm;
+
+ // now we'll be able to get inv bind matrix from joint id
+ joint_id_to_joint_index_map[joint_ids[i]] = i;
+ }
+ }
+ // morph controller
+ else {
+ }
+
+ return true;
+ }
+
+ COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId& controller_uid)
+ {
+ if (controller_id_to_geom_id_map.find(controller_uid) == controller_id_to_geom_id_map.end())
+ return NULL;
+
+ return &controller_id_to_geom_id_map[controller_uid];
+ }
+};
+
+class MeshImporter
+{
+private:
+
+ Scene *scene;
+ ArmatureImporter *armature_importer;
+
+ std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
+ // this structure is used to assign material indices to faces
+ // it holds a portion of Mesh faces and corresponds to a DAE primitive list (<triangles>, <polylist>, etc.)
+ struct Primitive {
+ MFace *mface;
+ unsigned int totface;
};
+ typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
+ std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; // crazy name!
+ // maps for assigning textures to uv layers
+ //std::map<COLLADAFW::TextureMapId, char*> set_layername_map;
+ std::map<COLLADAFW::TextureMapId, std::vector<MTex*> > index_mtex_map;
+
class UVDataWrapper
{
COLLADAFW::MeshVertexData *mVData;
@@ -248,125 +407,347 @@
}
};
-public:
+ void set_face_indices(MFace *mface, unsigned int *indices, bool quad)
+ {
+ mface->v1 = indices[0];
+ mface->v2 = indices[1];
+ mface->v3 = indices[2];
+ if (quad) mface->v4 = indices[3];
+ }
- /** Constructor. */
- Writer(bContext *C, const char *filename) : mContext(C), mFilename(filename) {};
+ // change face indices order so that v4 is not 0
+ void rotate_face_indices(MFace *mface) {
+ mface->v4 = mface->v1;
+ mface->v1 = mface->v2;
+ mface->v2 = mface->v3;
+ mface->v3 = 0;
+ }
- /** Destructor. */
- ~Writer() {};
-
- bool write()
+ void set_face_uv(MTFace *mtface, UVDataWrapper &uvs, int uv_set_index,
+ COLLADAFW::IndexList& index_list, int index, bool quad)
{
- COLLADASaxFWL::Loader loader;
- COLLADAFW::Root root(&loader, this);
+ int uv_indices[4][2];
- // XXX report error
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list