* Export cameras and lights.
* Import materials. TODO: Assign materials to objects.
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
#include "DNA_image_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_lamp_types.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -43,6 +45,11 @@ extern "C"
|
||||
#include <COLLADASWTexture.h>
|
||||
#include <COLLADASWLibraryMaterials.h>
|
||||
#include <COLLADASWBindMaterial.h>
|
||||
#include <COLLADASWLibraryCameras.h>
|
||||
#include <COLLADASWLibraryLights.h>
|
||||
#include <COLLADASWInstanceCamera.h>
|
||||
#include <COLLADASWInstanceLight.h>
|
||||
#include <COLLADASWCameraOptic.h>
|
||||
|
||||
#include <vector>
|
||||
#include <algorithm> // std::find
|
||||
@@ -114,6 +121,34 @@ void forEachMeshObjectInScene(Scene *sce, Functor &f)
|
||||
}
|
||||
}
|
||||
|
||||
template<class Functor>
|
||||
void forEachCameraObjectInScene(Scene *sce, Functor &f)
|
||||
{
|
||||
Base *base= (Base*) sce->base.first;
|
||||
while(base) {
|
||||
Object *ob = base->object;
|
||||
|
||||
if (ob->type == OB_CAMERA && ob->data) {
|
||||
f(ob);
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Functor>
|
||||
void forEachLampObjectInScene(Scene *sce, Functor &f)
|
||||
{
|
||||
Base *base= (Base*) sce->base.first;
|
||||
while(base) {
|
||||
Object *ob = base->object;
|
||||
|
||||
if (ob->type == OB_LAMP && ob->data) {
|
||||
f(ob);
|
||||
}
|
||||
base= base->next;
|
||||
}
|
||||
}
|
||||
|
||||
// used in forEachMaterialInScene
|
||||
template <class MaterialFunctor>
|
||||
class ForEachMaterialFunctor
|
||||
@@ -184,10 +219,10 @@ public:
|
||||
DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH);
|
||||
Mesh *me = (Mesh*)ob->data;
|
||||
std::string geom_name(id_name(ob));
|
||||
|
||||
|
||||
// openMesh(geoId, geoName, meshId)
|
||||
openMesh(geom_name, "", "");
|
||||
|
||||
|
||||
// writes <source> for vertex coords
|
||||
createVertsSource(geom_name, dm);
|
||||
|
||||
@@ -497,6 +532,8 @@ public:
|
||||
|
||||
// write <node>s
|
||||
forEachMeshObjectInScene(sce, *this);
|
||||
forEachCameraObjectInScene(sce, *this);
|
||||
forEachLampObjectInScene(sce, *this);
|
||||
|
||||
// </visual_scene> </library_visual_scenes>
|
||||
closeVisualScene();
|
||||
@@ -507,6 +544,7 @@ public:
|
||||
// called for each object
|
||||
void operator()(Object *ob) {
|
||||
COLLADASW::Node node(mSW);
|
||||
std::string ob_name(id_name(ob));
|
||||
node.start();
|
||||
|
||||
node.addTranslate(ob->loc[0], ob->loc[1], ob->loc[2]);
|
||||
@@ -521,37 +559,50 @@ public:
|
||||
QuatToAxisAngle(quat, axis, &angle);
|
||||
angle_deg = angle * 180.0f / M_PI;
|
||||
node.addRotate(axis[0], axis[1], axis[2], angle_deg);
|
||||
|
||||
node.addScale(ob->size[0], ob->size[1], ob->size[2]);
|
||||
|
||||
COLLADASW::InstanceGeometry instGeom(mSW);
|
||||
std::string ob_name(id_name(ob));
|
||||
instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, ob_name));
|
||||
|
||||
for(int a = 0; a < ob->totcol; a++) {
|
||||
Material *ma = give_current_material(ob, a+1);
|
||||
|
||||
COLLADASW::BindMaterial& bm = instGeom.getBindMaterial();
|
||||
COLLADASW::InstanceMaterialList& iml = bm.getInstanceMaterialList();
|
||||
std::string matid(id_name(ma));
|
||||
COLLADASW::InstanceMaterial im(matid, COLLADASW::URI
|
||||
(COLLADABU::Utils::EMPTY_STRING,
|
||||
matid));
|
||||
|
||||
// create <bind_vertex_input> for each uv layer
|
||||
Mesh *me = (Mesh*)ob->data;
|
||||
int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
|
||||
|
||||
// <instance_geometry>
|
||||
if (ob->type == OB_MESH) {
|
||||
COLLADASW::InstanceGeometry instGeom(mSW);
|
||||
instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, ob_name));
|
||||
|
||||
for (int b = 0; b < totlayer; b++) {
|
||||
char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, b);
|
||||
im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", b));
|
||||
for(int a = 0; a < ob->totcol; a++) {
|
||||
Material *ma = give_current_material(ob, a+1);
|
||||
|
||||
COLLADASW::BindMaterial& bm = instGeom.getBindMaterial();
|
||||
COLLADASW::InstanceMaterialList& iml = bm.getInstanceMaterialList();
|
||||
std::string matid(id_name(ma));
|
||||
COLLADASW::InstanceMaterial im(matid, COLLADASW::URI
|
||||
(COLLADABU::Utils::EMPTY_STRING,
|
||||
matid));
|
||||
|
||||
// create <bind_vertex_input> for each uv layer
|
||||
Mesh *me = (Mesh*)ob->data;
|
||||
int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
|
||||
|
||||
for (int b = 0; b < totlayer; b++) {
|
||||
char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, b);
|
||||
im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", b));
|
||||
}
|
||||
|
||||
iml.push_back(im);
|
||||
}
|
||||
|
||||
iml.push_back(im);
|
||||
instGeom.add();
|
||||
}
|
||||
|
||||
instGeom.add();
|
||||
|
||||
|
||||
// <instance_camera>
|
||||
else if (ob->type == OB_CAMERA) {
|
||||
COLLADASW::InstanceCamera instCam(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, ob_name));
|
||||
instCam.add();
|
||||
}
|
||||
|
||||
// <instance_light>
|
||||
else if (ob->type == OB_LAMP) {
|
||||
COLLADASW::InstanceLight instLa(mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, ob_name));
|
||||
instLa.add();
|
||||
}
|
||||
|
||||
node.end();
|
||||
}
|
||||
|
||||
@@ -818,6 +869,95 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class CamerasExporter: COLLADASW::LibraryCameras
|
||||
{
|
||||
public:
|
||||
CamerasExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryCameras(sw){}
|
||||
void exportCameras(Scene *sce)
|
||||
{
|
||||
openLibrary();
|
||||
|
||||
forEachCameraObjectInScene(sce, *this);
|
||||
|
||||
closeLibrary();
|
||||
}
|
||||
void operator()(Object *ob)
|
||||
{
|
||||
// XXX add other params later
|
||||
Camera *cam = (Camera*)ob->data;
|
||||
std::string cam_name(id_name(ob));
|
||||
if (cam->type == CAM_PERSP) {
|
||||
COLLADASW::PerspectiveOptic persp(mSW);
|
||||
persp.setXFov(1.0);
|
||||
//persp.setYFov(1.0);
|
||||
persp.setAspectRatio(1.0);
|
||||
persp.setZFar(cam->clipend);
|
||||
persp.setZNear(cam->clipsta);
|
||||
COLLADASW::Camera ccam(mSW, &persp, cam_name);
|
||||
addCamera(ccam);
|
||||
}
|
||||
else {
|
||||
COLLADASW::OrthographicOptic ortho(mSW);
|
||||
ortho.setXMag(1.0);
|
||||
//ortho.setYMag(1.0, true);
|
||||
ortho.setAspectRatio(1.0);
|
||||
ortho.setZFar(cam->clipend);
|
||||
ortho.setZNear(cam->clipsta);
|
||||
COLLADASW::Camera ccam(mSW, &ortho, cam_name);
|
||||
addCamera(ccam);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class LightsExporter: COLLADASW::LibraryLights
|
||||
{
|
||||
public:
|
||||
LightsExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryLights(sw){}
|
||||
void exportLights(Scene *sce)
|
||||
{
|
||||
openLibrary();
|
||||
|
||||
forEachLampObjectInScene(sce, *this);
|
||||
|
||||
closeLibrary();
|
||||
}
|
||||
void operator()(Object *ob)
|
||||
{
|
||||
Lamp *la = (Lamp*)ob->data;
|
||||
std::string la_name(id_name(ob));
|
||||
COLLADASW::Color col(la->r, la->g, la->b);
|
||||
|
||||
// sun
|
||||
if (la->type == LA_SUN) {
|
||||
COLLADASW::DirectionalLight cla(mSW, la_name, la->energy);
|
||||
cla.setColor(col);
|
||||
addLight(cla);
|
||||
}
|
||||
// hemi
|
||||
else if (la->type == LA_HEMI) {
|
||||
COLLADASW::AmbientLight cla(mSW, la_name, la->energy);
|
||||
cla.setColor(col);
|
||||
addLight(cla);
|
||||
}
|
||||
// spot
|
||||
// XXX add other params later
|
||||
else if (la->type == LA_SPOT) {
|
||||
COLLADASW::SpotLight cla(mSW, la_name, la->energy);
|
||||
cla.setColor(col);
|
||||
addLight(cla);
|
||||
}
|
||||
// lamp
|
||||
else if (la->type != LA_AREA) {
|
||||
COLLADASW::PointLight cla(mSW, la_name, la->energy);
|
||||
cla.setColor(col);
|
||||
addLight(cla);
|
||||
}
|
||||
else {
|
||||
// XXX write error
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename)
|
||||
{
|
||||
@@ -825,43 +965,51 @@ void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename)
|
||||
COLLADABU::NativeString(std::string(filename));
|
||||
COLLADASW::StreamWriter sw(native_filename);
|
||||
|
||||
//open <Collada>
|
||||
// open <Collada>
|
||||
sw.startDocument();
|
||||
|
||||
//<asset>
|
||||
// <asset>
|
||||
COLLADASW::Asset asset(&sw);
|
||||
// XXX ask blender devs about this?
|
||||
asset.setUnit("meter", 1.0);
|
||||
asset.setUpAxisType(COLLADASW::Asset::Z_UP);
|
||||
asset.add();
|
||||
|
||||
//<library_images>
|
||||
// <library_cameras>
|
||||
CamerasExporter ce(&sw);
|
||||
ce.exportCameras(sce);
|
||||
|
||||
// <library_lights>
|
||||
LightsExporter le(&sw);
|
||||
le.exportLights(sce);
|
||||
|
||||
// <library_images>
|
||||
ImagesExporter ie(&sw);
|
||||
ie.exportImages(sce);
|
||||
|
||||
//<library_effects>
|
||||
// <library_effects>
|
||||
EffectsExporter ee(&sw);
|
||||
ee.exportEffects(sce);
|
||||
|
||||
//<library_materials>
|
||||
// <library_materials>
|
||||
MaterialsExporter me(&sw);
|
||||
me.exportMaterials(sce);
|
||||
|
||||
//<library_geometries>
|
||||
// <library_geometries>
|
||||
GeometryExporter ge(&sw);
|
||||
ge.exportGeom(sce);
|
||||
|
||||
//<library_visual_scenes>
|
||||
// <library_visual_scenes>
|
||||
SceneExporter se(&sw);
|
||||
se.exportScene(sce);
|
||||
|
||||
//<scene>
|
||||
// <scene>
|
||||
std::string scene_name(id_name(sce));
|
||||
COLLADASW::Scene scene(&sw, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING,
|
||||
scene_name));
|
||||
scene.add();
|
||||
|
||||
//close <Collada>
|
||||
// close <Collada>
|
||||
sw.endDocument();
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "COLLADAFWTranslate.h"
|
||||
#include "COLLADAFWScale.h"
|
||||
#include "COLLADAFWRotate.h"
|
||||
#include "COLLADAFWEffect.h"
|
||||
|
||||
#include "COLLADASaxFWLLoader.h"
|
||||
|
||||
@@ -40,6 +41,7 @@ extern "C"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
#include "DocumentImporter.h"
|
||||
|
||||
@@ -97,6 +99,7 @@ private:
|
||||
bContext *mContext;
|
||||
|
||||
std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
|
||||
std::map<COLLADAFW::UniqueId, Material*> uid_material_map;
|
||||
|
||||
class UnitConverter
|
||||
{
|
||||
@@ -221,12 +224,12 @@ public:
|
||||
|
||||
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();
|
||||
@@ -239,13 +242,13 @@ public:
|
||||
// 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
|
||||
@@ -254,9 +257,9 @@ public:
|
||||
fprintf(stderr, "Couldn't find a mesh by UID.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
set_mesh(ob, uid_mesh_map[uid]);
|
||||
|
||||
|
||||
float rot[3][3];
|
||||
Mat3One(rot);
|
||||
|
||||
@@ -287,7 +290,7 @@ public:
|
||||
float rot_copy[3][3];
|
||||
float mat[3][3];
|
||||
AxisAngleToQuat(quat, axis, angle);
|
||||
|
||||
|
||||
QuatToMat3(quat, mat);
|
||||
Mat3CpyMat3(rot_copy, rot);
|
||||
Mat3MulMat3(rot, rot_copy, mat);
|
||||
@@ -312,7 +315,7 @@ public:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Mat3ToEul(rot, ob->rot);
|
||||
|
||||
}
|
||||
@@ -496,8 +499,9 @@ public:
|
||||
{
|
||||
// TODO: create and store a material.
|
||||
// Let it have 0 users for now.
|
||||
/*std::string name = material->getOriginalId();
|
||||
add_material(name);*/
|
||||
const std::string& str_mat_id = material->getOriginalId();
|
||||
Material *ma = add_material((char*)str_mat_id.c_str());
|
||||
this->uid_material_map[material->getInstantiatedEffect()] = ma;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -505,6 +509,79 @@ public:
|
||||
@return The writer should return true, if writing succeeded, false otherwise.*/
|
||||
virtual bool writeEffect( const COLLADAFW::Effect* effect )
|
||||
{
|
||||
|
||||
const COLLADAFW::UniqueId& uid = effect->getUniqueId();
|
||||
if (uid_material_map.find(uid) == uid_material_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 material by UID.\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
Material *ma = uid_material_map[uid];
|
||||
|
||||
COLLADAFW::CommonEffectPointerArray ef_array = effect->getCommonEffects();
|
||||
if (ef_array.getCount() < 1) {
|
||||
fprintf(stderr, "Effect hasn't got any common effects.\n");
|
||||
}
|
||||
|
||||
COLLADAFW::EffectCommon *ef = ef_array[0];
|
||||
COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType();
|
||||
|
||||
// blinn
|
||||
if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) {
|
||||
ma->spec_shader = MA_SPEC_BLINN;
|
||||
ma->spec = ef->getShininess().getFloatValue();
|
||||
}
|
||||
// phong
|
||||
else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) {
|
||||
ma->spec_shader = MA_SPEC_PHONG;
|
||||
ma->spec = ef->getShininess().getFloatValue();
|
||||
}
|
||||
// lambert
|
||||
else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) {
|
||||
ma->diff_shader = MA_DIFF_LAMBERT;
|
||||
}
|
||||
// default - lambert
|
||||
else {
|
||||
ma->diff_shader = MA_DIFF_LAMBERT;
|
||||
fprintf(stderr, "Current shader type is not supported.\n");
|
||||
}
|
||||
// reflectivity
|
||||
ma->ray_mirror = ef->getReflectivity().getFloatValue();
|
||||
// index of refraction
|
||||
ma->ang = ef->getIndexOfRefraction().getFloatValue();
|
||||
|
||||
COLLADAFW::Color col;
|
||||
// diffuse
|
||||
if (ef->getDiffuse().isColor()) {
|
||||
col = ef->getDiffuse().getColor();
|
||||
ma->r = col.getRed();
|
||||
ma->g = col.getGreen();
|
||||
ma->b = col.getBlue();
|
||||
}
|
||||
// ambient
|
||||
if (ef->getAmbient().isColor()) {
|
||||
col = ef->getAmbient().getColor();
|
||||
ma->ambr = col.getRed();
|
||||
ma->ambg = col.getGreen();
|
||||
ma->ambb = col.getBlue();
|
||||
}
|
||||
// specular
|
||||
if (ef->getSpecular().isColor()) {
|
||||
col = ef->getSpecular().getColor();
|
||||
ma->specr = col.getRed();
|
||||
ma->specg = col.getGreen();
|
||||
ma->specb = col.getBlue();
|
||||
}
|
||||
// reflective
|
||||
if (ef->getReflective().isColor()) {
|
||||
col = ef->getReflective().getColor();
|
||||
ma->mirr = col.getRed();
|
||||
ma->mirg = col.getGreen();
|
||||
ma->mirb = col.getBlue();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user