Browse Source

add assimp stuff

rdb 14 years ago
parent
commit
19e73932d2

+ 36 - 0
pandatool/src/assimp/Sources.pp

@@ -0,0 +1,36 @@
+#begin lib_target
+  #define BUILD_TARGET $[HAVE_ASSIMP]
+
+  #define TARGET p3assimp
+  #define BUILDING_DLL BUILDING_ASSIMP
+  #define LOCAL_LIBS \
+    pandatoolbase
+  #define USE_PACKAGES assimp
+
+  #define OTHER_LIBS \
+    egg2pg:c egg:c pandaegg:m \
+    pstatclient:c mathutil:c linmath:c putil:c \
+    gobj:c chan:c parametrics:c pgraph:c pgraphnodes:c \
+    pnmimage:c grutil:c collide:c tform:c text:c \
+    char:c dgraph:c display:c device:c cull:c \
+    downloader:c pipeline:c \
+    event:c gsgbase:c lerp:c movies:c \
+    panda:m \
+    pandabase:c express:c pandaexpress:m \
+    interrogatedb:c prc:c dconfig:c dtoolconfig:m \
+    dtoolutil:c dtoolbase:c dtool:m \
+    assimp:c
+
+  #define SOURCES \
+    assimpLoader.cxx assimpLoader.h \
+    config_assimp.cxx config_assimp.h \
+    loaderFileTypeAssimp.cxx loaderFileTypeAssimp.h \
+    pandaIOStream.cxx pandaIOStream.h \
+    pandaIOSystem.cxx pandaIOSystem.h \
+    pandaLogger.cxx pandaLogger.h
+
+  #define INSTALL_HEADERS \
+    assimpLoader.h \
+    config_assimp.h loaderFileTypeAssimp.h
+
+#end lib_target

+ 14 - 0
pandatool/src/assimp/assimpLoader.I

@@ -0,0 +1,14 @@
+// Filename: assimpLoader.I
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+

+ 644 - 0
pandatool/src/assimp/assimpLoader.cxx

@@ -0,0 +1,644 @@
+// Filename: assimpLoader.cxx
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "assimpLoader.h"
+
+#include "geomNode.h"
+#include "luse.h"
+#include "geomVertexWriter.h"
+#include "geomPoints.h"
+#include "geomLines.h"
+#include "geomTriangles.h"
+#include "pnmFileTypeRegistry.h"
+#include "pnmImage.h"
+#include "materialAttrib.h"
+#include "textureAttrib.h"
+#include "cullFaceAttrib.h"
+#include "lightNode.h"
+#include "ambientLight.h"
+#include "directionalLight.h"
+#include "spotlight.h"
+#include "pointLight.h"
+#include "look_at.h"
+#include "texturePool.h"
+
+#include "pandaIOSystem.h"
+#include "pandaLogger.h"
+
+#include "aiPostProcess.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+AssimpLoader::
+AssimpLoader() :
+  _error (false),
+  _geoms (NULL) {
+
+  PandaLogger::set_default();
+  _importer.SetIOHandler(new PandaIOSystem);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+AssimpLoader::
+~AssimpLoader() {
+  _importer.FreeScene();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::get_extensions
+//       Access: Public
+//  Description: Returns a space-separated list of extensions that
+//               Assimp can load, without the leading dots.
+////////////////////////////////////////////////////////////////////
+void AssimpLoader::
+get_extensions(string &ext) const {
+  aiString aexts;
+  _importer.GetExtensionList(aexts);
+
+  // The format is like: *.mdc;*.mdl;*.mesh.xml;*.mot
+  char *sub = strtok(aexts.data, ";");
+  while (sub != NULL) {
+    ext += sub + 2;
+    sub = strtok(NULL, ";");
+
+    if (sub != NULL) {
+      ext += ' ';
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::read
+//       Access: Public
+//  Description: Reads from the indicated file.
+////////////////////////////////////////////////////////////////////
+bool AssimpLoader::
+read(const Filename &filename) {
+  _filename = filename;
+
+  // I really don't know why we need to flip the winding order,
+  // but otherwise the models I tested with are showing inside out.
+  _scene = _importer.ReadFile(_filename.c_str(), aiProcess_Triangulate | aiProcess_GenUVCoords | aiProcess_FlipWindingOrder);
+  if (_scene == NULL) {
+    _error = true;
+    return false;
+  }
+
+  _error = false;
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::build_graph
+//       Access: Public
+//  Description: Converts scene graph structures into a Panda3D
+//               scene graph, with _root being the root node.
+////////////////////////////////////////////////////////////////////
+void AssimpLoader::
+build_graph() {
+  nassertv(_scene != NULL); // read() must be called first
+  nassertv(!_error);        // and have succeeded
+
+  // Protect the import process
+  MutexHolder holder(_lock);
+
+  _root = new ModelRoot(_filename.get_basename());
+
+  // Import all of the embedded textures first.
+  _textures = new PT(Texture)[_scene->mNumTextures];
+  for (size_t i = 0; i < _scene->mNumTextures; ++i) {
+    load_texture(i);
+  }
+
+  // Then the materials.
+  _mat_states = new CPT(RenderState)[_scene->mNumMaterials];
+  for (size_t i = 0; i < _scene->mNumMaterials; ++i) {
+    load_material(i);
+  }
+
+  // And then the meshes.
+  _geoms = new PT(Geom)[_scene->mNumMeshes];
+  _geom_matindices = new unsigned int[_scene->mNumMeshes];
+  for (size_t i = 0; i < _scene->mNumMeshes; ++i) {
+    load_mesh(i);
+  }
+
+  // And now the node structure.
+  if (_scene->mRootNode != NULL) {
+    load_node(*_scene->mRootNode, _root);
+  }
+
+  // And lastly, the lights.
+  for (size_t i = 0; i < _scene->mNumLights; ++i) {
+    load_light(*_scene->mLights[i]);
+  }
+
+  delete[] _textures;
+  delete[] _mat_states;
+  delete[] _geoms;
+  delete[] _geom_matindices;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::load_texture
+//       Access: Private
+//  Description: Converts an aiTexture into a Texture.
+////////////////////////////////////////////////////////////////////
+void AssimpLoader::
+load_texture(size_t index) {
+  const aiTexture &tex = *_scene->mTextures[index];
+
+  PT(Texture) ptex = new Texture;
+
+  if (tex.mHeight == 0) {
+    // Compressed texture.
+    assimp_cat.debug()
+      << "Reading embedded compressed texture with format " << tex.achFormatHint << " and size " << tex.mWidth << "\n";
+    stringstream str;
+    str.write((char*) tex.pcData, tex.mWidth);
+
+    if (strncmp(tex.achFormatHint, "dds", 3) == 0) {
+      ptex->read_dds(str);
+
+    } else {
+      const PNMFileTypeRegistry *reg = PNMFileTypeRegistry::get_global_ptr();
+      PNMFileType *ftype;
+      PNMImage img;
+
+      // Work around a bug in Assimp, it sometimes writes jp instead of jpg
+      if (strncmp(tex.achFormatHint, "jp\0", 3) == 0) {
+        ftype = reg->get_type_from_extension("jpg");
+      } else {
+        ftype = reg->get_type_from_extension(tex.achFormatHint);
+      }
+
+      if (img.read(str, "", ftype)) {
+        ptex->load(img);
+      } else {
+        ptex = NULL;
+      }
+    }
+  } else {
+    assimp_cat.debug()
+      << "Reading embedded raw texture with size " << tex.mWidth << "x" << tex.mHeight << "\n";
+
+    ptex->setup_2d_texture(tex.mWidth, tex.mHeight, Texture::T_unsigned_byte, Texture::F_rgba);
+    PTA_uchar data = ptex->modify_ram_image();
+
+    size_t p = 0;
+    for (size_t i = 0; i < tex.mWidth * tex.mHeight; ++i) {
+      const aiTexel &texel = tex.pcData[i];
+      data[p++] = texel.b;
+      data[p++] = texel.g;
+      data[p++] = texel.r;
+      data[p++] = texel.a;
+    }
+  }
+
+  //ostringstream path;
+  //path << "/tmp/" << index << ".png";
+  //ptex->write(path.str());
+
+  _textures[index] = ptex;
+
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::load_texture_stage
+//       Access: Private
+//  Description: Converts an aiMaterial into a RenderState.
+////////////////////////////////////////////////////////////////////
+void AssimpLoader::
+load_texture_stage(const aiMaterial &mat, const aiTextureType &ttype, CPT(TextureAttrib) &tattr) {
+  aiString path;
+  aiTextureMapping mapping;
+  unsigned int uvindex;
+  float blend;
+  aiTextureOp op;
+  aiTextureMapMode mapmode;
+
+  for (size_t i = 0; i < mat.GetTextureCount(ttype); ++i) {
+    mat.GetTexture(ttype, i, &path, &mapping, NULL, &blend, &op, &mapmode);
+
+    if (AI_SUCCESS != mat.Get(AI_MATKEY_UVWSRC(ttype, i), uvindex)) {
+      // If there's no texture coordinate set for this texture,
+      // assume that it's the same as the index on the stack.
+      //TODO: if there's only one set on the mesh,
+      //      force everything to use just the first stage.
+      uvindex = i;
+    }
+
+    stringstream str;
+    str << uvindex;
+    PT(TextureStage) stage = new TextureStage(str.str());
+    if (uvindex > 0) {
+      stage->set_texcoord_name(InternalName::get_texcoord_name(str.str()));
+    }
+    PT(Texture) ptex = NULL;
+
+    // I'm not sure if this is the right way to handle it, as
+    // I couldn't find much information on embedded textures.
+    if (path.data[0] == '*') {
+      long num = strtol(path.data + 1, NULL, 10);
+      ptex = _textures[num];
+
+    } else if (path.length > 0) {
+      Filename fn = Filename::from_os_specific(string(path.data, path.length));
+
+      // Try to find the file by moving up twice in the hierarchy.
+      VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
+      Filename dir (_filename);
+      _filename.make_canonical();
+      dir = _filename.get_dirname();
+
+      // Quake 3 BSP doesn't specify an extension for textures.
+      if (vfs->is_regular_file(Filename(dir, fn))) {
+        fn = Filename(dir, fn);
+      } else if (vfs->is_regular_file(Filename(dir, fn + ".tga"))) {
+        fn = Filename(dir, fn + ".tga");
+      } else if (vfs->is_regular_file(Filename(dir, fn + ".jpg"))) {
+        fn = Filename(dir, fn + ".jpg");
+      } else {
+        dir = _filename.get_dirname();
+        if (vfs->is_regular_file(Filename(dir, fn))) {
+          fn = Filename(dir, fn);
+        } else if (vfs->is_regular_file(Filename(dir, fn + ".tga"))) {
+          fn = Filename(dir, fn + ".tga");
+        } else if (vfs->is_regular_file(Filename(dir, fn + ".jpg"))) {
+          fn = Filename(dir, fn + ".jpg");
+        }
+      }
+
+      ptex = TexturePool::load_texture(fn);
+    }
+
+    if (ptex != NULL) {
+      tattr = DCAST(TextureAttrib, tattr->add_on_stage(stage, ptex));
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::load_material
+//       Access: Private
+//  Description: Converts an aiMaterial into a RenderState.
+////////////////////////////////////////////////////////////////////
+void AssimpLoader::
+load_material(size_t index) {
+  const aiMaterial &mat = *_scene->mMaterials[index];
+
+  CPT(RenderState) state = RenderState::make_empty();
+
+  aiColor3D col;
+  bool have;
+  int ival;
+  float fval;
+
+  // XXX a lot of this is untested.
+
+  // First do the material attribute.
+  PT(Material) pmat = new Material;
+  have = false;
+  if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_DIFFUSE, col)) {
+    pmat->set_diffuse(Colorf(col.r, col.g, col.b, 1));
+    have = true;
+  }
+  if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_SPECULAR, col)) {
+    if (AI_SUCCESS == mat.Get(AI_MATKEY_SHININESS_STRENGTH, fval)) {
+      pmat->set_specular(Colorf(col.r * fval, col.g * fval, col.b * fval, 1));
+    } else {
+      pmat->set_specular(Colorf(col.r, col.g, col.b, 1));
+    }
+    have = true;
+  }
+  if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_AMBIENT, col)) {
+    pmat->set_specular(Colorf(col.r, col.g, col.b, 1));
+    have = true;
+  }
+  if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_EMISSIVE, col)) {
+    pmat->set_emission(Colorf(col.r, col.g, col.b, 1));
+    have = true;
+  }
+  if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_TRANSPARENT, col)) {
+    //FIXME: ???
+  }
+  if (AI_SUCCESS == mat.Get(AI_MATKEY_SHININESS, fval)) {
+    pmat->set_shininess(fval);
+    have = true;
+  }
+  if (have) {
+    state = state->add_attrib(MaterialAttrib::make(pmat));
+  }
+
+  // Wireframe.
+  if (AI_SUCCESS == mat.Get(AI_MATKEY_ENABLE_WIREFRAME, ival)) {
+    if (ival) {
+      state = state->add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_wireframe));
+    } else {
+      state = state->add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled));
+    }
+  }
+
+  // Backface culling.  Not sure if this is also supposed to
+  // set the twoside flag in the material, I'm guessing not.
+  if (AI_SUCCESS == mat.Get(AI_MATKEY_TWOSIDED, ival)) {
+    if (ival) {
+      state = state->add_attrib(CullFaceAttrib::make(CullFaceAttrib::M_cull_none));
+    } else {
+      state = state->add_attrib(CullFaceAttrib::make_default());
+    }
+  }
+
+  // And let's not forget the textures!
+  CPT(TextureAttrib) tattr = DCAST(TextureAttrib, TextureAttrib::make());
+  load_texture_stage(mat, aiTextureType_DIFFUSE, tattr);
+  load_texture_stage(mat, aiTextureType_LIGHTMAP, tattr);
+  if (tattr->get_num_on_stages() > 0) {
+    state = state->add_attrib(tattr);
+  }
+
+  _mat_states[index] = state;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::load_mesh
+//       Access: Private
+//  Description: Converts an aiMesh into a Geom.
+////////////////////////////////////////////////////////////////////
+void AssimpLoader::
+load_mesh(size_t index) {
+  const aiMesh &mesh = *_scene->mMeshes[index];
+
+  // Create the vertex format.
+  PT(GeomVertexArrayFormat) aformat = new GeomVertexArrayFormat;
+  aformat->add_column(InternalName::get_vertex(), 3, Geom::NT_float32, Geom::C_point);
+  if (mesh.HasNormals()) {
+    aformat->add_column(InternalName::get_normal(), 3, Geom::NT_float32, Geom::C_vector);
+  }
+  if (mesh.HasVertexColors(0)) {
+    aformat->add_column(InternalName::get_color(), 4, Geom::NT_float32, Geom::C_color);
+  }
+  unsigned int num_uvs = mesh.GetNumUVChannels();
+  if (num_uvs > 0) {
+    // UV sets are named texcoord, texcoord.1, texcoord.2...
+    aformat->add_column(InternalName::get_texcoord(), 3, Geom::NT_float32, Geom::C_texcoord);
+    for (unsigned int u = 1; u < num_uvs; ++u) {
+      ostringstream out;
+      out << u;
+      aformat->add_column(InternalName::get_texcoord_name(out.str()), 3, Geom::NT_float32, Geom::C_texcoord);
+    }
+  }
+  //TODO: if there is only one UV set, hackily iterate over the texture stages and clear the texcoord name things
+
+  PT(GeomVertexFormat) format = new GeomVertexFormat;
+  format->add_array(aformat);
+
+  // Create the GeomVertexData.
+  string name (mesh.mName.data, mesh.mName.length);
+  PT(GeomVertexData) vdata = new GeomVertexData(name, GeomVertexFormat::register_format(format), Geom::UH_static);
+  vdata->unclean_set_num_rows(mesh.mNumVertices);
+
+  // Read out the vertices.
+  GeomVertexWriter vertex (vdata, InternalName::get_vertex());
+  for (size_t i = 0; i < mesh.mNumVertices; ++i) {
+    const aiVector3D &vec = mesh.mVertices[i];
+    vertex.add_data3f(vec.x, vec.y, vec.z);
+  }
+
+  // Now the normals, if any.
+  if (mesh.HasNormals()) {
+    GeomVertexWriter normal (vdata, InternalName::get_normal());
+    for (size_t i = 0; i < mesh.mNumVertices; ++i) {
+      const aiVector3D &vec = mesh.mNormals[i];
+      normal.add_data3f(vec.x, vec.y, vec.z);
+    }
+  }
+
+  // Vertex colors, if any.  We only import the first set.
+  if (mesh.HasVertexColors(0)) {
+    GeomVertexWriter color (vdata, InternalName::get_color());
+    for (size_t i = 0; i < mesh.mNumVertices; ++i) {
+      const aiColor4D &col = mesh.mColors[0][i];
+      color.add_data4f(col.r, col.g, col.b, col.a);
+    }
+  }
+
+  // Now the texture coordinates.
+  if (num_uvs > 0) {
+    // UV sets are named texcoord, texcoord.1, texcoord.2...
+    GeomVertexWriter texcoord0 (vdata, InternalName::get_texcoord());
+    for (size_t i = 0; i < mesh.mNumVertices; ++i) {
+      const aiVector3D &vec = mesh.mTextureCoords[0][i];
+      texcoord0.add_data3f(vec.x, vec.y, vec.z);
+    }
+    for (unsigned int u = 1; u < num_uvs; ++u) {
+      ostringstream out;
+      out << u;
+      GeomVertexWriter texcoord (vdata, InternalName::get_texcoord_name(out.str()));
+      for (size_t i = 0; i < mesh.mNumVertices; ++i) {
+        const aiVector3D &vec = mesh.mTextureCoords[u][i];
+        texcoord.add_data3f(vec.x, vec.y, vec.z);
+      }
+    }
+  }
+
+  // Now read out the primitives.
+  // Keep in mind that we called ReadFile with the aiProcess_Triangulate
+  // flag earlier, so we don't have to worry about polygons.
+  PT(GeomPoints) points = new GeomPoints(Geom::UH_static);
+  PT(GeomLines) lines = new GeomLines(Geom::UH_static);
+  PT(GeomTriangles) triangles = new GeomTriangles(Geom::UH_static);
+
+  // Now add the vertex indices.
+  for (size_t i = 0; i < mesh.mNumFaces; ++i) {
+    const aiFace &face = mesh.mFaces[i];
+
+    if (face.mNumIndices == 0) {
+      // It happens, strangely enough.
+      continue;
+    } else if (face.mNumIndices == 1) {
+      points->add_vertex(face.mIndices[0]);
+      points->close_primitive();
+    } else if (face.mNumIndices == 2) {
+      lines->add_vertices(face.mIndices[0], face.mIndices[1]);
+      lines->close_primitive();
+    } else if (face.mNumIndices == 3) {
+      triangles->add_vertices(face.mIndices[0], face.mIndices[1], face.mIndices[2]);
+      triangles->close_primitive();
+    } else {
+      nassertd(false) continue;
+    }
+  }
+
+  // Create a geom and add the primitives to it.
+  PT(Geom) geom = new Geom(vdata);
+  if (points->get_num_primitives() > 0) {
+    geom->add_primitive(points);
+  }
+  if (lines->get_num_primitives() > 0) {
+    geom->add_primitive(lines);
+  }
+  if (triangles->get_num_primitives() > 0) {
+    geom->add_primitive(triangles);
+  }
+
+  _geoms[index] = geom;
+  _geom_matindices[index] = mesh.mMaterialIndex;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::load_node
+//       Access: Private
+//  Description: Converts an aiNode into a PandaNode.
+////////////////////////////////////////////////////////////////////
+void AssimpLoader::
+load_node(const aiNode &node, PandaNode *parent) {
+  PT(PandaNode) pnode;
+
+  // Create the node and give it a name.
+  string name (node.mName.data, node.mName.length);
+  if (node.mNumMeshes > 0) {
+    pnode = new GeomNode(name);
+  } else {
+    pnode = new PandaNode(name);
+  }
+  parent->add_child(pnode);
+
+  // Load in the transformation matrix.
+  const aiMatrix4x4 &t = node.mTransformation;
+  if (!t.IsIdentity()) {
+    LMatrix4f mat(t.a1, t.b1, t.c1, t.d1,
+                  t.a2, t.b2, t.c2, t.d2,
+                  t.a3, t.b3, t.c3, t.d3,
+                  t.a4, t.b4, t.c4, t.d4);
+    pnode->set_transform(TransformState::make_mat(mat));
+  }
+
+  for (size_t i = 0; i < node.mNumChildren; ++i) {
+    load_node(*node.mChildren[i], pnode);
+  }
+
+  if (node.mNumMeshes > 0) {
+    // Remember, we created this as GeomNode earlier.
+    PT(GeomNode) gnode = DCAST(GeomNode, pnode);
+    size_t meshIndex;
+
+    // If there's only mesh, don't bother using a per-geom state.
+    if (node.mNumMeshes == 1) {
+      meshIndex = node.mMeshes[0];
+      gnode->add_geom(_geoms[meshIndex]);
+      gnode->set_state(_mat_states[_geom_matindices[meshIndex]]);
+
+    } else {
+      for (size_t i = 0; i < node.mNumMeshes; ++i) {
+        meshIndex = node.mMeshes[i];
+        gnode->add_geom(_geoms[node.mMeshes[i]],
+          _mat_states[_geom_matindices[meshIndex]]);
+      }
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: AssimpLoader::load_light
+//       Access: Private
+//  Description: Converts an aiLight into a LightNode.
+////////////////////////////////////////////////////////////////////
+void AssimpLoader::
+load_light(const aiLight &light) {
+  string name (light.mName.data, light.mName.length);
+  assimp_cat.debug() << "Found light '" << name << "'\n";
+
+  aiColor3D col;
+  aiVector3D vec;
+
+  PT(LightNode) lnode;
+
+  switch (light.mType) {
+  case aiLightSource_DIRECTIONAL: {
+    PT(DirectionalLight) dlight = new DirectionalLight(name);
+    lnode = DCAST(LightNode, dlight);
+
+    col = light.mColorSpecular;
+    dlight->set_specular_color(Colorf(col.r, col.g, col.b, 1));
+
+    vec = light.mPosition;
+    dlight->set_point(LPoint3f(vec.x, vec.y, vec.z));
+
+    vec = light.mDirection;
+    dlight->set_direction(LVector3f(vec.x, vec.y, vec.z));
+    break; }
+
+  case aiLightSource_POINT: {
+    PT(PointLight) plight = new PointLight(name);
+    lnode = DCAST(LightNode, plight);
+
+    col = light.mColorSpecular;
+    plight->set_specular_color(Colorf(col.r, col.g, col.b, 1));
+
+    vec = light.mPosition;
+    plight->set_point(LPoint3f(vec.x, vec.y, vec.z));
+
+    plight->set_attenuation(LVecBase3f(light.mAttenuationConstant,
+                                       light.mAttenuationLinear,
+                                       light.mAttenuationQuadratic));
+    break; }
+
+  case aiLightSource_SPOT: {
+    PT(Spotlight) plight = new Spotlight(name);
+    lnode = DCAST(LightNode, plight);
+
+    col = light.mColorSpecular;
+    plight->set_specular_color(Colorf(col.r, col.g, col.b, 1));
+
+    plight->set_attenuation(LVecBase3f(light.mAttenuationConstant,
+                                       light.mAttenuationLinear,
+                                       light.mAttenuationQuadratic));
+
+    plight->get_lens()->set_fov(light.mAngleOuterCone);
+    //TODO: translate mAngleInnerCone to an exponent, somehow
+
+    // This *should* be about right.
+    vec = light.mDirection;
+    LPoint3f pos (light.mPosition.x, light.mPosition.y, light.mPosition.z);
+    LQuaternionf quat;
+    ::look_at(quat, LPoint3f(vec.x, vec.y, vec.z), LVector3f::up());
+    plight->set_transform(TransformState::make_pos_quat_scale(pos, quat, LVecBase3f(1, 1, 1)));
+    break; }
+
+  default:
+    assimp_cat.warning() << "Light '" << name << "' has an unknown type!\n";
+    return;
+  }
+
+  // If there's an ambient color, add it as ambient light.
+  LVecBase4f ambient (col.r, col.g, col.b, 0);
+  if (ambient != LVecBase4f::zero()) {
+    PT(AmbientLight) alight = new AmbientLight(name);
+    col = light.mColorAmbient;
+    alight->set_color(ambient);
+    _root->add_child(alight);
+  }
+
+  _root->add_child(lnode);
+  col = light.mColorDiffuse;
+  lnode->set_color(Colorf(col.r, col.g, col.b, 1));
+}

+ 67 - 0
pandatool/src/assimp/assimpLoader.h

@@ -0,0 +1,67 @@
+// Filename: assimpLoader.h
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef ASSIMPLOADER_H
+#define ASSIMPLOADER_H
+
+#include "config_assimp.h"
+#include "filename.h"
+#include "modelRoot.h"
+#include "texture.h"
+
+#include "aiScene.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : AssimpLoader
+// Description : Class that interfaces with Assimp and builds Panda
+//               nodes to represent the Assimp structures.
+//               The loader should be reusable.
+////////////////////////////////////////////////////////////////////
+class AssimpLoader : public TypedReferenceCount {
+public:
+  AssimpLoader();
+  virtual ~AssimpLoader();
+
+  void get_extensions(string &ext) const;
+
+  bool read(const Filename &filename);
+  void build_graph();
+
+public:
+  bool _error;
+  PT(ModelRoot) _root;
+  Filename _filename;
+  Mutex _lock;
+
+private:
+  Assimp::Importer _importer;
+  const aiScene *_scene;
+
+  // These arrays are temporarily used during the build_graph run.
+  PT(Texture) *_textures;
+  CPT(RenderState) *_mat_states;
+  PT(Geom) *_geoms;
+  unsigned int *_geom_matindices;
+
+  void load_texture(size_t index);
+  void load_texture_stage(const aiMaterial &mat, const aiTextureType &ttype, CPT(TextureAttrib) &tattr);
+  void load_material(size_t index);
+  void load_mesh(size_t index);
+  void load_node(const aiNode &node, PandaNode *parent);
+  void load_light(const aiLight &light);
+};
+
+#include "assimpLoader.I"
+
+#endif

+ 49 - 0
pandatool/src/assimp/config_assimp.cxx

@@ -0,0 +1,49 @@
+// Filename: config_assimp.cxx
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "config_assimp.h"
+
+#include "loaderFileTypeAssimp.h"
+
+#include "dconfig.h"
+#include "loaderFileTypeRegistry.h"
+
+ConfigureDef(config_assimp);
+NotifyCategoryDef(assimp, "");
+
+ConfigureFn(config_assimp) {
+  init_libassimp();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: init_libassimp
+//  Description: Initializes the library.  This must be called at
+//               least once before any of the functions or classes in
+//               this library can be used.  Normally it will be
+//               called by the static initializers and need not be
+//               called explicitly, but special cases exist.
+////////////////////////////////////////////////////////////////////
+void
+init_libassimp() {
+  static bool initialized = false;
+  if (initialized) {
+    return;
+  }
+  initialized = true;
+
+  LoaderFileTypeAssimp::init_type();
+
+  LoaderFileTypeRegistry *reg = LoaderFileTypeRegistry::get_global_ptr();
+  reg->register_type(new LoaderFileTypeAssimp);
+}

+ 29 - 0
pandatool/src/assimp/config_assimp.h

@@ -0,0 +1,29 @@
+// Filename: config_assimp.h
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef CONFIG_ASSIMP_H
+#define CONFIG_ASSIMP_H
+
+#include "pandatoolbase.h"
+
+#include "assimp.hpp"
+
+#include "dconfig.h"
+
+ConfigureDecl(config_assimp, EXPCL_ASSIMP, EXPTP_ASSIMP);
+NotifyCategoryDecl(assimp, EXPCL_ASSIMP, EXPTP_ASSIMP);
+
+extern EXPCL_ASSIMP void init_libassimp();
+
+#endif

+ 106 - 0
pandatool/src/assimp/loaderFileTypeAssimp.cxx

@@ -0,0 +1,106 @@
+// Filename: loaderFileTypeAssimp.cxx
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "loaderFileTypeAssimp.h"
+#include "config_assimp.h"
+#include "assimpLoader.h"
+
+TypeHandle LoaderFileTypeAssimp::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: LoaderFileTypeAssimp::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+LoaderFileTypeAssimp::
+LoaderFileTypeAssimp() : _loader(new AssimpLoader) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LoaderFileTypeAssimp::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+LoaderFileTypeAssimp::
+~LoaderFileTypeAssimp() {
+  if (_loader != NULL) {
+    delete _loader;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LoaderFileTypeAssimp::get_name
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+string LoaderFileTypeAssimp::
+get_name() const {
+  return "Assimp Importer";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LoaderFileTypeAssimp::get_extension
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+string LoaderFileTypeAssimp::
+get_extension() const {
+  return "";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LoaderFileTypeAssimp::get_additional_extensions
+//       Access: Public, Virtual
+//  Description: Returns a space-separated list of extension, in
+//               addition to the one returned by get_extension(), that
+//               are recognized by this converter.
+////////////////////////////////////////////////////////////////////
+string LoaderFileTypeAssimp::
+get_additional_extensions() const {
+  string exts;
+  _loader->get_extensions(exts);
+  return exts;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LoaderFileTypeAssimp::supports_compressed
+//       Access: Published, Virtual
+//  Description: Returns true if this file type can transparently load
+//               compressed files (with a .pz extension), false
+//               otherwise.
+////////////////////////////////////////////////////////////////////
+bool LoaderFileTypeAssimp::
+supports_compressed() const {
+  return true;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: LoaderFileTypeAssimp::load_file
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+PT(PandaNode) LoaderFileTypeAssimp::
+load_file(const Filename &path, const LoaderOptions &options,
+          BamCacheRecord *record) const {
+
+  assimp_cat.info()
+    << "Reading " << path << "\n";
+
+  if (!_loader->read(path)) {
+    return NULL;
+  }
+
+  _loader->build_graph();
+  return DCAST(PandaNode, _loader->_root);
+}

+ 63 - 0
pandatool/src/assimp/loaderFileTypeAssimp.h

@@ -0,0 +1,63 @@
+// Filename: loaderFileTypeAssimp.h
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef LOADERFILETYPEASSIMP_H
+#define LOADERFILETYPEASSIMP_H
+
+#include "config_assimp.h"
+#include "loaderFileType.h"
+
+class AssimpLoader;
+
+////////////////////////////////////////////////////////////////////
+//       Class : LoaderFileTypeAssimp
+// Description : This defines the Loader interface that uses the
+//               Assimp library to load various model formats.
+////////////////////////////////////////////////////////////////////
+class EXPCL_ASSIMP LoaderFileTypeAssimp : public LoaderFileType {
+public:
+  LoaderFileTypeAssimp();
+  virtual ~LoaderFileTypeAssimp();
+
+  virtual string get_name() const;
+  virtual string get_extension() const;
+  virtual string get_additional_extensions() const;
+  virtual bool supports_compressed() const;
+
+  virtual PT(PandaNode) load_file(const Filename &path, const LoaderOptions &options,
+                                  BamCacheRecord *record) const;
+
+public:
+  AssimpLoader *_loader;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    LoaderFileType::init_type();
+    register_type(_type_handle, "LoaderFileTypeAssimp",
+                  LoaderFileType::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#endif
+

+ 104 - 0
pandatool/src/assimp/pandaIOStream.cxx

@@ -0,0 +1,104 @@
+// Filename: pandaIOStream.cxx
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pandaIOStream.h"
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOStream::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+PandaIOStream::
+PandaIOStream(istream &stream) : _istream(stream) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOStream::FileSize
+//       Access: Public
+//  Description: Returns the size of this file.
+////////////////////////////////////////////////////////////////////
+size_t PandaIOStream::
+FileSize() const {
+  nassertr(false, 0);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOStream::Flush
+//       Access: Public
+//  Description: See fflush.
+////////////////////////////////////////////////////////////////////
+void PandaIOStream::
+Flush() {
+  nassertv(false);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOStream::Read
+//       Access: Public
+//  Description: See fread.
+////////////////////////////////////////////////////////////////////
+size_t PandaIOStream::
+Read(void *buffer, size_t size, size_t count) {
+  _istream.read((char*) buffer, size * count);
+  return _istream.gcount();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOStream::Seek
+//       Access: Public
+//  Description: See fseek.
+////////////////////////////////////////////////////////////////////
+aiReturn PandaIOStream::
+Seek(size_t offset, aiOrigin origin) {
+  switch (origin) {
+  case aiOrigin_SET:
+    _istream.seekg(offset, ios::beg);
+    break;
+
+  case aiOrigin_CUR:
+    _istream.seekg(offset, ios::cur);
+    break;
+
+  case aiOrigin_END:
+    _istream.seekg(offset, ios::end);
+    break;
+  }
+
+  if (_istream.good()) {
+    return AI_SUCCESS;
+  } else {
+    return AI_FAILURE;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOStream::Tell
+//       Access: Public
+//  Description: See ftell.
+////////////////////////////////////////////////////////////////////
+size_t PandaIOStream::
+Tell() const {
+  _istream.tellg();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOStream::Write
+//       Access: Public
+//  Description: See fwrite.
+////////////////////////////////////////////////////////////////////
+size_t PandaIOStream::
+Write(const void *buffer, size_t size, size_t count) {
+  nassertr(false, 0);
+}

+ 48 - 0
pandatool/src/assimp/pandaIOStream.h

@@ -0,0 +1,48 @@
+// Filename: pandaIOStream.h
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PANDAIOSTREAM_H
+#define PANDAIOSTREAM_H
+
+#include "config_assimp.h"
+
+#include "IOStream.h"
+
+class PandaIOSystem;
+
+////////////////////////////////////////////////////////////////////
+//       Class : PandaIOStream
+// Description : Custom implementation of Assimp::IOStream.  It
+//               simply wraps around an istream object, and is
+//               unable to write.
+////////////////////////////////////////////////////////////////////
+class PandaIOStream : public Assimp::IOStream {
+public:
+  PandaIOStream(istream &stream);
+  virtual ~PandaIOStream() {};
+
+  size_t FileSize() const;
+  void Flush();
+  size_t Read(void *pvBuffer, size_t pSize, size_t pCount);
+  aiReturn Seek(size_t pOffset, aiOrigin pOrigin);
+  size_t Tell() const;
+  size_t Write(const void *buffer, size_t size, size_t count);
+
+private:
+  istream &_istream;
+
+  friend class PandaIOSystem;
+};
+
+#endif

+ 99 - 0
pandatool/src/assimp/pandaIOSystem.cxx

@@ -0,0 +1,99 @@
+// Filename: pandaIOSystem.cxx
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pandaIOSystem.h"
+#include "pandaIOStream.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOSystem::Constructor
+//       Access: Public
+//  Description: Initializes the object with the given VFS, or the
+//               global one if none was specified.
+////////////////////////////////////////////////////////////////////
+PandaIOSystem::
+PandaIOSystem(VirtualFileSystem *vfs) : _vfs(vfs) {
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOSystem::Exists
+//       Access: Public
+//  Description: Returns true if the file exists, duh.
+////////////////////////////////////////////////////////////////////
+bool PandaIOSystem::
+Exists(const char *file) const {
+  Filename fn = Filename::from_os_specific(file);
+  return _vfs->exists(fn);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOSystem::Close
+//       Access: Public
+//  Description: Closes the indicated file stream.
+////////////////////////////////////////////////////////////////////
+void PandaIOSystem::
+Close(Assimp::IOStream *file) {
+  PandaIOStream *pstr = (PandaIOStream*) file;
+  _vfs->close_read_file(&pstr->_istream);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOSystem::ComparePaths
+//       Access: Public
+//  Description: Returns true if the two paths point to the same
+//               file, false if not.
+////////////////////////////////////////////////////////////////////
+bool PandaIOSystem::
+ComparePaths(const char *p1, const char *p2) const {
+  Filename fn1 = Filename::from_os_specific(p1);
+  Filename fn2 = Filename::from_os_specific(p2);
+  fn1.make_canonical();
+  fn2.make_canonical();
+  return fn1 == fn2;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOSystem::getOsSeparator
+//       Access: Public
+//  Description: Returns the path separator for this operating
+//               system.
+////////////////////////////////////////////////////////////////////
+char PandaIOSystem::
+getOsSeparator() const {
+#ifdef _WIN32
+  return '\\';
+#else
+  return '/';
+#endif
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaIOSystem::Open
+//       Access: Public
+//  Description: Opens the indicated file.
+////////////////////////////////////////////////////////////////////
+Assimp::IOStream *PandaIOSystem::
+Open(const char *file, const char *mode) {
+  Filename fn = Filename::from_os_specific(file);
+
+  if (mode[0] == 'r') {
+    istream *stream = _vfs->open_read_file(file, true);
+    if (stream == NULL) {
+      return NULL;
+    }
+    return new PandaIOStream(*stream);
+
+  } else {
+    nassertr(false, NULL); // Not implemented on purpose.
+  }
+}

+ 43 - 0
pandatool/src/assimp/pandaIOSystem.h

@@ -0,0 +1,43 @@
+// Filename: pandaIOSystem.h
+// Created by:  rdb (29Mar11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PANDAIOSYSTEM_H
+#define PANDAIOSYSTEM_H
+
+#include "config_assimp.h"
+#include "virtualFileSystem.h"
+
+#include "IOSystem.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PandaIOSystem
+// Description : Custom implementation of Assimp::IOSystem.
+////////////////////////////////////////////////////////////////////
+class PandaIOSystem : public Assimp::IOSystem {
+public:
+  PandaIOSystem(VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr());
+  virtual ~PandaIOSystem() {};
+
+  void Close(Assimp::IOStream *file);
+  bool ComparePaths(const char *p1, const char *p2) const;
+  bool Exists(const char *file) const;
+  char getOsSeparator() const;
+  Assimp::IOStream *Open(const char *file, const char *mode);
+
+private:
+  VirtualFileSystem *_vfs;
+};
+
+#endif
+

+ 71 - 0
pandatool/src/assimp/pandaLogger.cxx

@@ -0,0 +1,71 @@
+// Filename: pandaLogger.cxx
+// Created by:  rdb (05May11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pandaLogger.h"
+
+#include "DefaultLogger.h"
+
+PandaLogger *PandaLogger::_ptr = NULL;
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaLogger::set_default
+//       Access: Public
+//  Description: Makes sure there's a global PandaLogger object and
+//               makes sure that it is Assimp's default logger.
+////////////////////////////////////////////////////////////////////
+void PandaLogger::
+set_default() {
+  if (_ptr == NULL) {
+    _ptr = new PandaLogger;
+  }
+  if (_ptr != Assimp::DefaultLogger::get()) {
+    Assimp::DefaultLogger::set(_ptr);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaLogger::OnDebug
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+void PandaLogger::OnDebug(const char *message) {
+  assimp_cat.debug() << message << "\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaLogger::OnError
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+void PandaLogger::OnError(const char *message) {
+  assimp_cat.error() << message << "\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaLogger::OnInfo
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+void PandaLogger::OnInfo(const char *message) {
+  assimp_cat.info() << message << "\n";
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PandaLogger::OnWarn
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+void PandaLogger::OnWarn(const char *message) {
+  assimp_cat.warning() << message << "\n";
+}

+ 44 - 0
pandatool/src/assimp/pandaLogger.h

@@ -0,0 +1,44 @@
+// Filename: pandaLogger.h
+// Created by:  rdb (05May11)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PANDALOGGER_H
+#define PANDALOGGER_H
+
+#include "config_assimp.h"
+
+#include "Logger.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : PandaLogger
+// Description : Custom implementation of Assimp::Logger.  It
+//               simply wraps around the assimp_cat methods.
+////////////////////////////////////////////////////////////////////
+class PandaLogger : public Assimp::Logger {
+public:
+  static void set_default();
+
+protected:
+  INLINE bool attachStream(Assimp::LogStream*, unsigned int) {};
+  INLINE bool detatchStream(Assimp::LogStream*, unsigned int) {};
+
+  void OnDebug(const char *message);
+  void OnError(const char *message);
+  void OnInfo(const char *message);
+  void OnWarn(const char *message);
+
+private:
+  static PandaLogger *_ptr;
+};
+
+#endif

+ 11 - 0
pandatool/src/pandatoolbase/pandatoolsymbols.h

@@ -19,6 +19,14 @@
 
 #if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
 
+#ifdef BUILDING_ASSIMP
+  #define EXPCL_ASSIMP __declspec(dllexport)
+  #define EXPTP_ASSIMP
+#else
+  #define EXPCL_ASSIMP __declspec(dllimport)
+  #define EXPTP_ASSIMP extern
+#endif
+
 #ifdef BUILDING_PTLOADER
   #define EXPCL_PTLOADER __declspec(dllexport)
   #define EXPTP_PTLOADER
@@ -29,6 +37,9 @@
 
 #else   /* !WIN32_VC */
 
+#define EXPCL_ASSIMP
+#define EXPTP_ASSIMP
+
 #define EXPCL_PTLOADER
 #define EXPTP_PTLOADER
 

+ 4 - 4
pandatool/src/ptloader/config_ptloader.cxx

@@ -94,10 +94,10 @@ init_libptloader() {
   ObjToEggConverter *obj = new ObjToEggConverter;
   reg->register_type(new LoaderFileTypePandatool(obj));
 
-#ifdef HAVE_FCOLLADA
-  DAEToEggConverter *dae = new DAEToEggConverter;
-  reg->register_type(new LoaderFileTypePandatool(dae));
-#endif
+//#ifdef HAVE_FCOLLADA
+//  DAEToEggConverter *dae = new DAEToEggConverter;
+//  reg->register_type(new LoaderFileTypePandatool(dae));
+//#endif
 
 #ifdef HAVE_MAYA
   // Register the Maya converter as a deferred type.  We don't compile