42 #include <assimp/postprocess.h> 44 using std::ostringstream;
45 using std::stringstream;
53 : joint_vertex_xform(joint_vertex_xform), weight(weight)
75 _importer.FreeScene();
85 _importer.GetExtensionList(aexts);
88 char *sub = strtok(aexts.data,
";");
89 while (sub !=
nullptr) {
91 sub = strtok(
nullptr,
";");
104 _filename = filename;
106 unsigned int flags = aiProcess_Triangulate | aiProcess_GenUVCoords;
108 if (assimp_calc_tangent_space) {
109 flags |= aiProcess_CalcTangentSpace;
111 if (assimp_join_identical_vertices) {
112 flags |= aiProcess_JoinIdenticalVertices;
114 if (assimp_improve_cache_locality) {
115 flags |= aiProcess_ImproveCacheLocality;
117 if (assimp_remove_redundant_materials) {
118 flags |= aiProcess_RemoveRedundantMaterials;
120 if (assimp_fix_infacing_normals) {
121 flags |= aiProcess_FixInfacingNormals;
123 if (assimp_optimize_meshes) {
124 flags |= aiProcess_OptimizeMeshes;
126 if (assimp_optimize_graph) {
127 flags |= aiProcess_OptimizeGraph;
129 if (assimp_flip_winding_order) {
130 flags |= aiProcess_FlipWindingOrder;
133 _scene = _importer.ReadFile(_filename.c_str(), flags);
134 if (_scene ==
nullptr) {
149 nassertv(_scene !=
nullptr);
158 _textures =
new PT(
Texture)[_scene->mNumTextures];
159 for (
size_t i = 0; i < _scene->mNumTextures; ++i) {
164 _mat_states =
new CPT(
RenderState)[_scene->mNumMaterials];
165 for (
size_t i = 0; i < _scene->mNumMaterials; ++i) {
170 _geoms =
new PT(
Geom)[_scene->mNumMeshes];
171 _geom_matindices =
new unsigned int[_scene->mNumMeshes];
172 for (
size_t i = 0; i < _scene->mNumMeshes; ++i) {
177 if (_scene->mRootNode !=
nullptr) {
178 load_node(*_scene->mRootNode, _root);
182 for (
size_t i = 0; i < _scene->mNumLights; ++i) {
183 load_light(*_scene->mLights[i]);
187 delete[] _mat_states;
189 delete[] _geom_matindices;
195 const aiNode *AssimpLoader::
196 find_node(
const aiNode &root,
const aiString &name) {
199 if (root.mName == name) {
202 for (
size_t i = 0; i < root.mNumChildren; ++i) {
203 node = find_node(*root.mChildren[i], name);
217 load_texture(
size_t index) {
218 const aiTexture &tex = *_scene->mTextures[index];
222 if (tex.mHeight == 0) {
225 <<
"Reading embedded compressed texture with format " << tex.achFormatHint <<
" and size " << tex.mWidth <<
"\n";
227 str.
write((
char*) tex.pcData, tex.mWidth);
229 if (strncmp(tex.achFormatHint,
"dds", 3) == 0) {
238 if (strncmp(tex.achFormatHint,
"jp\0", 3) == 0) {
244 if (img.
read(str,
"", ftype)) {
252 <<
"Reading embedded raw texture with size " << tex.mWidth <<
"x" << tex.mHeight <<
"\n";
254 ptex->setup_2d_texture(tex.mWidth, tex.mHeight, Texture::T_unsigned_byte, Texture::F_rgba);
255 PTA_uchar data = ptex->modify_ram_image();
258 for (
size_t i = 0; i < tex.mWidth * tex.mHeight; ++i) {
259 const aiTexel &texel = tex.pcData[i];
270 _textures[index] = ptex;
278 load_texture_stage(
const aiMaterial &mat,
const aiTextureType &ttype, CPT(
TextureAttrib) &tattr) {
280 aiTextureMapping mapping;
281 unsigned int uvindex;
284 aiTextureMapMode mapmode;
286 for (
size_t i = 0; i < mat.GetTextureCount(ttype); ++i) {
287 mat.GetTexture(ttype, i, &path, &mapping,
nullptr, &blend, &op, &mapmode);
289 if (AI_SUCCESS != mat.Get(AI_MATKEY_UVWSRC(ttype, i), uvindex)) {
306 if (path.data[0] ==
'*') {
307 long num = strtol(path.data + 1,
nullptr, 10);
308 ptex = _textures[num];
310 }
else if (path.length > 0) {
340 if (ptex !=
nullptr) {
341 tattr = DCAST(
TextureAttrib, tattr->add_on_stage(stage, ptex));
350 load_material(
size_t index) {
351 const aiMaterial &mat = *_scene->mMaterials[index];
353 CPT(
RenderState) state = RenderState::make_empty();
365 if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_DIFFUSE, col)) {
369 if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_SPECULAR, col)) {
370 if (AI_SUCCESS == mat.Get(AI_MATKEY_SHININESS_STRENGTH, fval)) {
371 pmat->set_specular(LColor(col.r * fval, col.g * fval, col.b * fval, 1));
373 pmat->set_specular(LColor(col.r, col.g, col.b, 1));
377 if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_AMBIENT, col)) {
378 pmat->set_specular(LColor(col.r, col.g, col.b, 1));
381 if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_EMISSIVE, col)) {
382 pmat->set_emission(LColor(col.r, col.g, col.b, 1));
385 if (AI_SUCCESS == mat.Get(AI_MATKEY_COLOR_TRANSPARENT, col)) {
388 if (AI_SUCCESS == mat.Get(AI_MATKEY_SHININESS, fval)) {
389 pmat->set_shininess(fval);
393 state = state->add_attrib(MaterialAttrib::make(pmat));
397 if (AI_SUCCESS == mat.Get(AI_MATKEY_ENABLE_WIREFRAME, ival)) {
399 state = state->add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_wireframe));
401 state = state->add_attrib(RenderModeAttrib::make(RenderModeAttrib::M_filled));
407 if (AI_SUCCESS == mat.Get(AI_MATKEY_TWOSIDED, ival)) {
409 state = state->add_attrib(CullFaceAttrib::make(CullFaceAttrib::M_cull_none));
411 state = state->add_attrib(CullFaceAttrib::make_default());
417 load_texture_stage(mat, aiTextureType_DIFFUSE, tattr);
418 load_texture_stage(mat, aiTextureType_LIGHTMAP, tattr);
420 state = state->add_attrib(tattr);
423 _mat_states[index] = state;
431 const aiMatrix4x4 &t = node.mTransformation;
432 LMatrix4 mat(t.a1, t.b1, t.c1, t.d1,
433 t.a2, t.b2, t.c2, t.d2,
434 t.a3, t.b3, t.c3, t.d3,
435 t.a4, t.b4, t.c4, t.d4);
439 <<
"Creating joint for: " << node.mName.C_Str() <<
"\n";
441 for (
size_t i = 0; i < node.mNumChildren; ++i) {
442 if (_bonemap.find(node.mChildren[i]->mName.C_Str()) != _bonemap.end()) {
443 create_joint(character, bundle, joint, *node.mChildren[i]);
452 create_anim_channel(
const aiAnimation &anim,
AnimBundle *bundle,
AnimGroup *parent,
const aiNode &node) {
456 aiNodeAnim *node_anim =
nullptr;
457 for (
size_t i = 0; i < anim.mNumChannels; ++i) {
458 if (anim.mChannels[i]->mNodeName == node.mName) {
459 node_anim = anim.mChannels[i];
465 <<
"Found channel for node: " << node.mName.C_Str() <<
"\n";
473 PTA_stdfloat tablex = PTA_stdfloat::empty_array(node_anim->mNumPositionKeys);
474 PTA_stdfloat tabley = PTA_stdfloat::empty_array(node_anim->mNumPositionKeys);
475 PTA_stdfloat tablez = PTA_stdfloat::empty_array(node_anim->mNumPositionKeys);
476 for (
size_t i = 0; i < node_anim->mNumPositionKeys; ++i) {
477 tablex[i] = node_anim->mPositionKeys[i].mValue.x;
478 tabley[i] = node_anim->mPositionKeys[i].mValue.y;
479 tablez[i] = node_anim->mPositionKeys[i].mValue.z;
481 group->set_table(
'x', tablex);
482 group->set_table(
'y', tabley);
483 group->set_table(
'z', tablez);
486 PTA_stdfloat tableh = PTA_stdfloat::empty_array(node_anim->mNumRotationKeys);
487 PTA_stdfloat tablep = PTA_stdfloat::empty_array(node_anim->mNumRotationKeys);
488 PTA_stdfloat tabler = PTA_stdfloat::empty_array(node_anim->mNumRotationKeys);
489 for (
size_t i = 0; i < node_anim->mNumRotationKeys; ++i) {
490 aiQuaternion ai_quat = node_anim->mRotationKeys[i].mValue;
491 LVecBase3 hpr = LQuaternion(ai_quat.w, ai_quat.x, ai_quat.y, ai_quat.z).get_hpr();
492 tableh[i] = hpr.get_x();
493 tablep[i] = hpr.get_y();
494 tabler[i] = hpr.get_z();
496 group->set_table(
'h', tableh);
497 group->set_table(
'p', tablep);
498 group->set_table(
'r', tabler);
501 PTA_stdfloat tablei = PTA_stdfloat::empty_array(node_anim->mNumScalingKeys);
502 PTA_stdfloat tablej = PTA_stdfloat::empty_array(node_anim->mNumScalingKeys);
503 PTA_stdfloat tablek = PTA_stdfloat::empty_array(node_anim->mNumScalingKeys);
504 for (
size_t i = 0; i < node_anim->mNumScalingKeys; ++i) {
505 tablei[i] = node_anim->mScalingKeys[i].mValue.x;
506 tablej[i] = node_anim->mScalingKeys[i].mValue.y;
507 tablek[i] = node_anim->mScalingKeys[i].mValue.z;
509 group->set_table(
'i', tablei);
510 group->set_table(
'j', tablej);
511 group->set_table(
'k', tablek);
515 <<
"No channel found for node: " << node.mName.C_Str() <<
"\n";
519 for (
size_t i = 0; i < node.mNumChildren; ++i) {
520 if (_bonemap.find(node.mChildren[i]->mName.C_Str()) != _bonemap.end()) {
521 create_anim_channel(anim, bundle, group, *node.mChildren[i]);
530 load_mesh(
size_t index) {
531 const aiMesh &mesh = *_scene->mMeshes[index];
535 if (mesh.HasBones()) {
537 <<
"Creating character for " << mesh.mName.C_Str() <<
"\n";
540 for (
size_t i = 0; i < mesh.mNumBones; ++i) {
541 const aiBone &bone = *mesh.mBones[i];
542 const aiNode *node = find_node(*_scene->mRootNode, bone.mName);
543 _bonemap[bone.mName.C_Str()] = node;
547 character =
new Character(mesh.mName.C_Str());
551 for (
size_t i = 0; i < mesh.mNumBones; ++i) {
552 const aiBone &bone = *mesh.mBones[i];
555 const aiNode *root = _bonemap[bone.mName.C_Str()];
556 while (root->mParent && _bonemap.find(root->mParent->mName.C_Str()) != _bonemap.end()) {
557 root = root->mParent;
561 if (character->
find_joint(root->mName.C_Str())) {
565 create_joint(character, bundle, skeleton, *root);
573 for (
size_t i = 0; i < mesh.mNumBones; ++i) {
574 const aiBone &bone = *mesh.mBones[i];
576 if (joint ==
nullptr) {
578 <<
"Could not find joint for bone: " << bone.mName.C_Str() <<
"\n";
584 for (
size_t j = 0; j < bone.mNumWeights; ++j) {
585 const aiVertexWeight &weight = bone.mWeights[j];
587 bone_weights[weight.mVertexId].push_back(
BoneWeight(jvt, weight.mWeight));
594 aformat->
add_column(InternalName::get_vertex(), 3, Geom::NT_stdfloat, Geom::C_point);
595 if (mesh.HasNormals()) {
596 aformat->add_column(InternalName::get_normal(), 3, Geom::NT_stdfloat, Geom::C_vector);
598 if (mesh.HasVertexColors(0)) {
599 aformat->add_column(InternalName::get_color(), 4, Geom::NT_stdfloat, Geom::C_color);
601 unsigned int num_uvs = mesh.GetNumUVChannels();
604 aformat->add_column(InternalName::get_texcoord(), 3, Geom::NT_stdfloat, Geom::C_texcoord);
605 for (
unsigned int u = 1; u < num_uvs; ++u) {
608 aformat->add_column(InternalName::get_texcoord_name(out.str()), 3, Geom::NT_stdfloat, Geom::C_texcoord);
613 tb_aformat->
add_column(InternalName::make(
"transform_blend"), 1, Geom::NT_uint16, Geom::C_index);
616 for (
size_t i = 0; i < _scene->mNumAnimations; ++i) {
617 aiAnimation &ai_anim = *_scene->mAnimations[i];
618 bool convert_anim =
false;
621 <<
"Checking to see if anim (" << ai_anim.mName.C_Str() <<
") matches character (" << mesh.mName.C_Str() <<
")\n";
622 for (
size_t j = 0; j < ai_anim.mNumChannels; ++j) {
624 <<
"Searching for " << ai_anim.mChannels[j]->mNodeName.C_Str() <<
" in bone map" <<
"\n";
625 if (_bonemap.find(ai_anim.mChannels[j]->mNodeName.C_Str()) != _bonemap.end()) {
633 <<
"Found animation (" << ai_anim.mName.C_Str() <<
") for character (" << mesh.mName.C_Str() <<
")\n";
636 unsigned int frames = 0;
637 for (
size_t j = 0; j < ai_anim.mNumChannels; ++j) {
638 if (ai_anim.mChannels[j]->mNumPositionKeys > frames) {
639 frames = ai_anim.mChannels[j]->mNumPositionKeys;
641 if (ai_anim.mChannels[j]->mNumRotationKeys > frames) {
642 frames = ai_anim.mChannels[j]->mNumRotationKeys;
644 if (ai_anim.mChannels[j]->mNumScalingKeys > frames) {
645 frames = ai_anim.mChannels[j]->mNumScalingKeys;
648 PN_stdfloat fps = frames / (ai_anim.mTicksPerSecond * ai_anim.mDuration);
650 <<
"FPS " << fps <<
"\n";
652 <<
"Frames " << frames <<
"\n";
657 for (
size_t i = 0; i < mesh.mNumBones; ++i) {
658 const aiBone &bone = *mesh.mBones[i];
661 const aiNode *root = _bonemap[bone.mName.C_Str()];
662 while (root->mParent && _bonemap.find(root->mParent->mName.C_Str()) != _bonemap.end()) {
663 root = root->mParent;
667 if (root->mName == bone.mName) {
668 create_anim_channel(ai_anim, bundle, skeleton, *root);
672 character->add_child(bundle_node);
684 format->add_array(tb_aformat);
688 format->set_animation(aspec);
692 string name (mesh.mName.data, mesh.mName.length);
695 vdata->set_transform_blend_table(tbtable);
697 vdata->unclean_set_num_rows(mesh.mNumVertices);
701 for (
size_t i = 0; i < mesh.mNumVertices; ++i) {
702 const aiVector3D &vec = mesh.mVertices[i];
703 vertex.add_data3(vec.x, vec.y, vec.z);
707 if (mesh.HasNormals()) {
709 for (
size_t i = 0; i < mesh.mNumVertices; ++i) {
710 const aiVector3D &vec = mesh.mNormals[i];
711 normal.add_data3(vec.x, vec.y, vec.z);
716 if (mesh.HasVertexColors(0)) {
718 for (
size_t i = 0; i < mesh.mNumVertices; ++i) {
719 const aiColor4D &col = mesh.mColors[0][i];
720 color.add_data4(col.r, col.g, col.b, col.a);
728 for (
size_t i = 0; i < mesh.mNumVertices; ++i) {
729 const aiVector3D &vec = mesh.mTextureCoords[0][i];
730 texcoord0.add_data3(vec.x, vec.y, vec.z);
732 for (
unsigned int u = 1; u < num_uvs; ++u) {
735 GeomVertexWriter texcoord (vdata, InternalName::get_texcoord_name(out.str()));
736 for (
size_t i = 0; i < mesh.mNumVertices; ++i) {
737 const aiVector3D &vec = mesh.mTextureCoords[u][i];
738 texcoord.add_data3(vec.x, vec.y, vec.z);
745 GeomVertexWriter transform_blend (vdata, InternalName::get_transform_blend());
747 for (
size_t i = 0; i < mesh.mNumVertices; ++i) {
750 for (
size_t j = 0; j < bone_weights[i].size(); ++j) {
751 tblend.
add_transform(bone_weights[i][j].joint_vertex_xform, bone_weights[i][j].weight);
753 transform_blend.add_data1i(tbtable->add_blend(tblend));
767 for (
size_t i = 0; i < mesh.mNumFaces; ++i) {
768 const aiFace &face = mesh.mFaces[i];
770 if (face.mNumIndices == 0) {
773 }
else if (face.mNumIndices == 1) {
774 points->add_vertex(face.mIndices[0]);
775 points->close_primitive();
776 }
else if (face.mNumIndices == 2) {
777 lines->add_vertices(face.mIndices[0], face.mIndices[1]);
778 lines->close_primitive();
779 }
else if (face.mNumIndices == 3) {
780 triangles->add_vertices(face.mIndices[0], face.mIndices[1], face.mIndices[2]);
781 triangles->close_primitive();
783 nassertd(
false) continue;
789 if (points->get_num_primitives() > 0) {
792 if (lines->get_num_primitives() > 0) {
793 geom->add_primitive(lines);
795 if (triangles->get_num_primitives() > 0) {
796 geom->add_primitive(triangles);
799 _geoms[index] = geom;
800 _geom_matindices[index] = mesh.mMaterialIndex;
803 _charmap[mesh.mName.C_Str()] = character;
811 load_node(
const aiNode &node,
PandaNode *parent) {
816 if (_bonemap.find(node.mName.C_Str()) != _bonemap.end()) {
821 string name (node.mName.data, node.mName.length);
822 if (node.mNumMeshes > 0) {
828 if (_charmap.find(node.mName.C_Str()) != _charmap.end()) {
829 character = _charmap[node.mName.C_Str()];
830 parent->add_child(character);
832 parent->add_child(pnode);
836 const aiMatrix4x4 &t = node.mTransformation;
837 if (!t.IsIdentity()) {
838 LMatrix4 mat(t.a1, t.b1, t.c1, t.d1,
839 t.a2, t.b2, t.c2, t.d2,
840 t.a3, t.b3, t.c3, t.d3,
841 t.a4, t.b4, t.c4, t.d4);
842 pnode->set_transform(TransformState::make_mat(mat));
845 for (
size_t i = 0; i < node.mNumChildren; ++i) {
846 load_node(*node.mChildren[i], pnode);
849 if (node.mNumMeshes > 0) {
855 if (node.mNumMeshes == 1) {
856 meshIndex = node.mMeshes[0];
857 gnode->add_geom(_geoms[meshIndex]);
858 gnode->set_state(_mat_states[_geom_matindices[meshIndex]]);
860 for (
size_t i = 0; i < node.mNumMeshes; ++i) {
861 meshIndex = node.mMeshes[i];
862 gnode->add_geom(_geoms[node.mMeshes[i]],
863 _mat_states[_geom_matindices[meshIndex]]);
868 assimp_cat.debug() <<
"Adding char to geom\n";
869 character->add_child(gnode);
878 load_light(
const aiLight &light) {
879 string name (light.mName.data, light.mName.length);
880 assimp_cat.debug() <<
"Found light '" << name <<
"'\n";
885 switch (light.mType) {
886 case aiLightSource_DIRECTIONAL: {
888 _root->add_child(dlight);
890 col = light.mColorDiffuse;
891 dlight->set_color(LColor(col.r, col.g, col.b, 1));
893 col = light.mColorSpecular;
894 dlight->set_specular_color(LColor(col.r, col.g, col.b, 1));
896 vec = light.mPosition;
897 dlight->set_point(LPoint3(vec.x, vec.y, vec.z));
899 vec = light.mDirection;
900 dlight->set_direction(LVector3(vec.x, vec.y, vec.z));
903 case aiLightSource_POINT: {
905 _root->add_child(plight);
907 col = light.mColorDiffuse;
908 plight->set_color(LColor(col.r, col.g, col.b, 1));
910 col = light.mColorSpecular;
911 plight->set_specular_color(LColor(col.r, col.g, col.b, 1));
913 vec = light.mPosition;
914 plight->set_point(LPoint3(vec.x, vec.y, vec.z));
916 plight->set_attenuation(LVecBase3(light.mAttenuationConstant,
917 light.mAttenuationLinear,
918 light.mAttenuationQuadratic));
921 case aiLightSource_SPOT: {
923 _root->add_child(plight);
925 col = light.mColorDiffuse;
926 plight->set_color(LColor(col.r, col.g, col.b, 1));
928 col = light.mColorSpecular;
929 plight->set_specular_color(LColor(col.r, col.g, col.b, 1));
931 plight->set_attenuation(LVecBase3(light.mAttenuationConstant,
932 light.mAttenuationLinear,
933 light.mAttenuationQuadratic));
935 plight->get_lens()->set_fov(light.mAngleOuterCone);
939 vec = light.mDirection;
940 LPoint3 pos (light.mPosition.x, light.mPosition.y, light.mPosition.z);
942 ::look_at(quat, LPoint3(vec.x, vec.y, vec.z), LVector3::up());
943 plight->set_transform(TransformState::make_pos_quat_scale(pos, quat, LVecBase3(1, 1, 1)));
953 assimp_cat.warning() <<
"Light '" << name <<
"' has an unknown type!\n";
958 col = light.mColorAmbient;
959 LVecBase4 ambient (col.r, col.g, col.b, 0);
960 if (ambient != LVecBase4::zero()) {
962 alight->set_color(ambient);
963 _root->add_child(alight);
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A node of this type is created automatically at the root of each model file that is loaded...
bool read(const Filename &filename)
Reads from the indicated file.
A light shining from infinitely far away in a particular direction, like sunlight.
std::string get_dirname() const
Returns the directory part of the filename.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A basic node of the scene graph or data graph.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
CharacterJoint * find_joint(const std::string &name) const
Returns a pointer to the joint with the given name, if there is such a joint, or NULL if there is no ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
The collection of all the joints and sliders in the character.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a series of disconnected points.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An animated character, with skeleton-morph animation and either soft- skinned or hard-skinned vertice...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This object describes how the vertex animation, if any, represented in a GeomVertexData is encoded...
get_num_on_stages
Returns the number of stages that are turned on by the attribute.
This is the root of an AnimChannel hierarchy.
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS's file system.
void build_graph()
Converts scene graph structures into a Panda3D scene graph, with _root being the root node...
Represents a texture object, which is typically a single 2-d image but may also represent a 1-d or 3-...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class of a family of classes that represent particular image file types that PNMImag...
bool read(const Filename &filename, PNMFileType *type=nullptr, bool report_unknown_type=true)
Reads the indicated image filename.
void get_extensions(std::string &ext) const
Returns a space-separated list of extensions that Assimp can load, without the leading dots...
bool make_canonical()
Converts this filename to a canonical name by replacing the directory part with the fully-qualified d...
void add_primitive(const GeomPrimitive *primitive)
Inserts a new GeomPrimitive structure to the Geom object.
A light source that seems to illuminate all points in space at once.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_diffuse
Specifies the diffuse color setting of the material.
static PNMFileTypeRegistry * get_global_ptr()
Returns a pointer to the global PNMFileTypeRegistry object.
Indicates the set of TextureStages and their associated Textures that should be applied to (or remove...
This is our own Panda specialization on the default STL vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_panda()
Specifies that vertex animation is to be performed by Panda.
This is the base class for AnimChannel and AnimBundle.
The name of a file, such as a texture file or an Egg file.
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for geometry primitives.
A light originating from a single point in space, and shining in a particular direction, with a cone-shaped falloff.
static Texture * load_texture(const Filename &filename, int primary_file_num_channels=0, bool read_mipmaps=false, const LoaderOptions &options=LoaderOptions())
Loads the given filename up into a texture, if it has not already been loaded, and returns the new te...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines the way an object appears in the presence of lighting.
PNMFileType * get_type_from_extension(const std::string &filename) const
Tries to determine what the PNMFileType is likely to be for a particular image file based on its exte...
static SparseArray lower_on(int on_bits)
Returns a SparseArray whose lower on_bits bits are on.
This represents a unique collection of RenderAttrib objects that correspond to a particular renderabl...
std::string get_basename() const
Returns the basename part of the filename.
Defines a series of disconnected line segments.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class maintains the set of all known PNMFileTypes in the universe.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool is_regular_file(const Filename &filename) const
Convenience function; returns true if the named file exists and is a regular file.
This represents one joint of the character's animation, containing an animating transform matrix...
set_texcoord_name
Indicate which set of UV's this texture stage will use.
Defines a series of disconnected triangles.
An animation channel that issues a matrix each frame, read from a table such as might have been read ...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a node that contains a pointer to an AnimBundle.
Defines the properties of a named stage of the multitexture pipeline.
static void set_default()
Makes sure there's a global PandaLogger object and makes sure that it is Assimp's default logger...
Custom implementation of Assimp::IOSystem.
A light originating from a single point in space, and shining in all directions.
A node that holds Geom objects, renderable pieces of geometry.
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes, and no drive letter) based on the supplied filename string that describes a filename in the local system conventions (for instance, on Windows, it may use backslashes or begin with a drive letter and a colon).
bool write(const Filename &fullpath)
Writes the texture to the named filename.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the base class for PartRoot and MovingPart.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.