* Objects are created and linked to meshes. 
* Since I don't know how to import per-face normals, they are generated automatically by mesh_calc_normals.
* Objects are imported with transformations but without rotation yet.
This commit is contained in:
Chingiz Dyussenov
2009-06-26 11:25:19 +00:00
parent ab183755da
commit 2f3b3e5f33

View File

@@ -15,6 +15,10 @@
#include "COLLADAFWArrayPrimitiveType.h"
#include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h"
#include "COLLADAFWPolygons.h"
#include "COLLADAFWTransformation.h"
#include "COLLADAFWTranslate.h"
#include "COLLADAFWScale.h"
#include "COLLADAFWRotate.h"
#include "COLLADASaxFWLLoader.h"
@@ -28,6 +32,7 @@ extern "C"
#include "BKE_object.h"
#include "BKE_image.h"
#include "BKE_material.h"
#include "BKE_library.h"
}
#include "DNA_object_types.h"
@@ -36,6 +41,8 @@ extern "C"
#include "DocumentImporter.h"
#include <string>
#include <map>
const char *primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
{
@@ -63,7 +70,6 @@ const char *primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
}
return "UNKNOWN";
}
const char *geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
{
switch (type) {
@@ -88,6 +94,8 @@ private:
bContext *mContext;
std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
class UnitConverter
{
private:
@@ -191,13 +199,102 @@ public:
@return The writer should return true, if writing succeeded, false otherwise.*/
virtual bool writeVisualScene ( const COLLADAFW::VisualScene* visualScene )
{
// This method is guaranteed to be called _after_ writeGeometry, writeMaterial, etc.
// for each <node> in <visual_scene>:
// create an Object
// if Mesh (previously created in writeGeometry) to which <node> corresponds exists, link Object with that mesh
// update: since we cannot link a Mesh with Object in
// writeGeometry because <geometry> does not reference <node>,
// we link Objects with Meshes at the end with method "finish".
// we link Objects with Meshes here
// XXX it's better to take Id than name
// TODO: create a new scene except the selected <visual_scene> - use current blender
// scene for it
Scene *sce = CTX_data_scene(mContext);
// Scene *sce = add_scene(visualScene->getName());
int i = 0;
for (i = 0; i < visualScene->getRootNodes().getCount(); i++) {
COLLADAFW::Node *node = visualScene->getRootNodes()[i];
// TODO: check node type
if (node->getType() != COLLADAFW::Node::NODE) {
continue;
}
Object *ob = add_object(sce, OB_MESH);
const std::string& id = node->getOriginalId();
if (id.length())
rename_id(&ob->id, (char*)id.c_str());
// XXX
// linking object with the first <instance_geometry>
// though a node may have more of them...
// TODO: join multiple <instance_geometry> meshes into 1, and link object with it
COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries();
if (geom.getCount() < 1) {
fprintf(stderr, "Node hasn't got any geometry.\n");
continue;
}
const COLLADAFW::UniqueId& uid = geom[0]->getInstanciatedObjectId();
if (uid_mesh_map.find(uid) == uid_mesh_map.end()) {
// XXX report to user
// this could happen if a mesh was not created
// (e.g. if it contains unsupported geometry)
fprintf(stderr, "Couldn't find a mesh by UID.\n");
continue;
}
set_mesh(ob, uid_mesh_map[uid]);
for (int k = 0; k < node->getTransformations().getCount(); k ++) {
COLLADAFW::Transformation *transform = node->getTransformations()[k];
COLLADAFW::Transformation::TransformationType type = transform->getTransformationType();
switch(type) {
case COLLADAFW::Transformation::TRANSLATE:
{
COLLADAFW::Translate *tra = (COLLADAFW::Translate*)transform;
COLLADABU::Math::Vector3& t = tra->getTranslation();
// X
ob->loc[0] = (float)t[0];
// Y
ob->loc[1] = (float)t[1];
// Z
ob->loc[2] = (float)t[2];
}
break;
case COLLADAFW::Transformation::ROTATE:
break;
case COLLADAFW::Transformation::SCALE:
{
COLLADABU::Math::Vector3& s = ((COLLADAFW::Scale*)transform)->getScale();
// X
ob->size[0] = (float)s[0];
// Y
ob->size[1] = (float)s[1];
// Z
ob->size[2] = (float)s[2];
}
break;
case COLLADAFW::Transformation::MATRIX:
break;
case COLLADAFW::Transformation::LOOKAT:
break;
case COLLADAFW::Transformation::SKEW:
break;
}
}
}
mVisualScenes.push_back(*visualScene);
return true;
@@ -269,25 +366,30 @@ public:
}
size_t totvert = cmesh->getPositions().getFloatValues()->getCount() / 3;
size_t totnorm = cmesh->getNormals().getFloatValues()->getCount() / 3;
//size_t totnorm = cmesh->getNormals().getFloatValues()->getCount() / 3;
if (cmesh->hasNormals() && totnorm != totvert) {
/*if (cmesh->hasNormals() && totnorm != totvert) {
fprintf(stderr, "Per-face normals are not supported.\n");
return true;
}
}*/
Mesh *me = add_mesh((char*)cgeom->getOriginalId().c_str());
const std::string& str_geom_id = cgeom->getOriginalId();
Mesh *me = add_mesh((char*)str_geom_id.c_str());
// store mesh ptr
// to link it later with Object
this->uid_mesh_map[cgeom->getUniqueId()] = me;
// vertices
me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
me->totvert = totvert;
float *pos_float_array = cmesh->getPositions().getFloatValues()->getData();
float *normals_float_array = NULL;
//float *normals_float_array = NULL;
if (cmesh->hasNormals())
/*if (cmesh->hasNormals())
normals_float_array = cmesh->getNormals().getFloatValues()->getData();
*/
MVert *mvert = me->mvert;
i = 0;
while (i < totvert) {
@@ -296,12 +398,12 @@ public:
mvert->co[1] = pos_float_array[1];
mvert->co[2] = pos_float_array[2];
if (normals_float_array) {
/*if (normals_float_array) {
mvert->no[0] = (short)(32767.0 * normals_float_array[0]);
mvert->no[1] = (short)(32767.0 * normals_float_array[1]);
mvert->no[2] = (short)(32767.0 * normals_float_array[2]);
normals_float_array += 3;
}
}*/
pos_float_array += 3;
mvert++;
@@ -362,65 +464,7 @@ public:
}
}
Object *ob = add_object(CTX_data_scene(mContext), OB_MESH);
set_mesh(ob, me);
// XXX: don't use editors module
// create a mesh object
// Object *ob = ED_object_add_type(mContext, OB_MESH);
// // enter editmode
// ED_object_enter_editmode(mContext, 0);
// Mesh *me = (Mesh*)ob->data;
// EditMesh *em = BKE_mesh_get_editmesh(me);
// // write geometry
// // currently only support <triangles>
// // read vertices
// std::vector<EditVert*> vertptr;
// COLLADAFW::MeshVertexData& vertdata = cmesh->getPositions();
// float *pos = vertdata.getFloatValues()->getData();
// size_t totpos = vertdata.getValuesCount() / 3;
// int i;
// for (i = 0; i < totpos; i++){
// float v[3] = {pos[i * 3 + 0],
// pos[i * 3 + 1],
// pos[i * 3 + 2]};
// EditVert *eve = addvertlist(em, v, 0);
// vertptr.push_back(eve);
// }
// COLLADAFW::MeshPrimitiveArray& apt = cmesh->getMeshPrimitives();
// // read primitives
// // TODO: support all primitive types
// for (i = 0; i < apt.getCount(); i++){
// COLLADAFW::MeshPrimitive *mp = apt.getData()[i];
// if (mp->getPrimitiveType() != COLLADAFW::MeshPrimitive::TRIANGLES){
// continue;
// }
// const size_t tottris = mp->getFaceCount();
// COLLADAFW::UIntValuesArray& indicesArray = mp->getPositionIndices();
// unsigned int *indices = indicesArray.getData();
// for (int j = 0; j < tottris; j++){
// addfacelist(em,
// vertptr[indices[j * 3 + 0]],
// vertptr[indices[j * 3 + 1]],
// vertptr[indices[j * 3 + 2]], 0, 0, 0);
// }
// }
// BKE_mesh_end_editmesh(me, em);
// // exit editmode
// ED_object_exit_editmode(mContext, EM_FREEDATA);
mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
return true;
}