X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fscene%2Fmodel%2Fmodel.cxx;h=cdd50861c478979587126563c501018b54eb4856;hb=9dc1b5f6f56c6fecdcfefc2a0a75695a89f323a2;hp=c2fdbb1cf18d7003f7b770d1dc3528bb3ede7985;hpb=40414f2823e426e12d2edfe7975a0ec9997b1f89;p=simgear.git diff --git a/simgear/scene/model/model.cxx b/simgear/scene/model/model.cxx index c2fdbb1c..cdd50861 100644 --- a/simgear/scene/model/model.cxx +++ b/simgear/scene/model/model.cxx @@ -7,268 +7,76 @@ #include #endif -#include +#include +#include +#include -#include // for strcmp() - -#include - -#include -#include -#include +#include #include -#include #include #include +#include -#include "animation.hxx" #include "model.hxx" SG_USING_STD(vector); - - -//////////////////////////////////////////////////////////////////////// -// Static utility functions. -//////////////////////////////////////////////////////////////////////// - -/** - * Callback to update an animation. - */ -static int -animation_callback (ssgEntity * entity, int mask) -{ - ((SGAnimation *)entity->getUserData())->update(); - return true; -} - - -/** - * Locate a named SSG node in a branch. - */ -static ssgEntity * -find_named_node (ssgEntity * node, const char * name) -{ - char * node_name = node->getName(); - if (node_name != 0 && !strcmp(name, node_name)) - return node; - else if (node->isAKindOf(ssgTypeBranch())) { - int nKids = node->getNumKids(); - for (int i = 0; i < nKids; i++) { - ssgEntity * result = - find_named_node(((ssgBranch*)node)->getKid(i), name); - if (result != 0) - return result; - } - } - return 0; -} - -/** - * Splice a branch in between all child nodes and their parents. - */ -static void -splice_branch (ssgBranch * branch, ssgEntity * child) -{ - int nParents = child->getNumParents(); - branch->addKid(child); - for (int i = 0; i < nParents; i++) { - ssgBranch * parent = child->getParent(i); - parent->replaceKid(child, branch); - } -} - -/** - * Make an offset matrix from rotations and position offset. - */ -void -sgMakeOffsetsMatrix( sgMat4 * result, double h_rot, double p_rot, double r_rot, - double x_off, double y_off, double z_off ) -{ - sgMat4 rot_matrix; - sgMat4 pos_matrix; - sgMakeRotMat4(rot_matrix, h_rot, p_rot, r_rot); - sgMakeTransMat4(pos_matrix, x_off, y_off, z_off); - sgMultMat4(*result, pos_matrix, rot_matrix); -} - - -void -sgMakeAnimation( ssgBranch * model, - const char * name, - vector &name_nodes, - SGPropertyNode *prop_root, - SGPropertyNode_ptr node, - double sim_time_sec ) -{ - SGAnimation * animation = 0; - const char * type = node->getStringValue("type", "none"); - if (!strcmp("none", type)) { - animation = new SGNullAnimation(node); - } else if (!strcmp("range", type)) { - animation = new SGRangeAnimation(prop_root, node); - } else if (!strcmp("billboard", type)) { - animation = new SGBillboardAnimation(node); - } else if (!strcmp("select", type)) { - animation = new SGSelectAnimation(prop_root, node); - } else if (!strcmp("spin", type)) { - animation = new SGSpinAnimation(prop_root, node, sim_time_sec ); - } else if (!strcmp("timed", type)) { - animation = new SGTimedAnimation(node); - } else if (!strcmp("rotate", type)) { - animation = new SGRotateAnimation(prop_root, node); - } else if (!strcmp("translate", type)) { - animation = new SGTranslateAnimation(prop_root, node); - } else if (!strcmp("scale", type)) { - animation = new SGScaleAnimation(prop_root, node); - } else if (!strcmp("texrotate", type)) { - animation = new SGTexRotateAnimation(prop_root, node); - } else if (!strcmp("textranslate", type)) { - animation = new SGTexTranslateAnimation(prop_root, node); - } else if (!strcmp("texmultiple", type)) { - animation = new SGTexMultipleAnimation(prop_root, node); - } else if (!strcmp("blend", type)) { - animation = new SGBlendAnimation(prop_root, node); - } else if (!strcmp("alpha-test", type)) { - animation = new SGAlphaTestAnimation(node); - } else { - animation = new SGNullAnimation(node); - SG_LOG(SG_INPUT, SG_WARN, "Unknown animation type " << type); - } - - if (name != 0) - animation->setName((char *)name); - - ssgEntity * object; - if (name_nodes.size() > 0) { - object = find_named_node(model, name_nodes[0]->getStringValue()); - if (object == 0) { - SG_LOG(SG_INPUT, SG_WARN, "Object " << name_nodes[0]->getStringValue() - << " not found"); - delete animation; - animation = 0; - } - } else { - object = model; - } - - if ( animation == 0 ) - return; - - ssgBranch * branch = animation->getBranch(); - splice_branch(branch, object); - - for (unsigned int i = 1; i < name_nodes.size(); i++) { - const char * name = name_nodes[i]->getStringValue(); - object = find_named_node(model, name); - if (object == 0) { - SG_LOG(SG_INPUT, SG_WARN, "Object " << name << " not found"); - delete animation; - animation = 0; - } - ssgBranch * oldParent = object->getParent(0); - branch->addKid(object); - oldParent->removeKid(object); - } - - animation->init(); - branch->setUserData(animation); - branch->setTravCallback(SSG_CALLBACK_PRETRAV, animation_callback); -} - - - - -//////////////////////////////////////////////////////////////////////// -// Global functions. -//////////////////////////////////////////////////////////////////////// - -ssgBranch * -sgLoad3DModel( const string &fg_root, const string &path, - SGPropertyNode *prop_root, - double sim_time_sec ) +osg::Texture2D* +SGLoadTexture2D(bool staticTexture, const std::string& path, + const osgDB::ReaderWriter::Options* options, + bool wrapu, bool wrapv, int) { - ssgBranch * model = 0; - SGPropertyNode props; - - // Load the 3D aircraft object itself - SGPath modelpath = path; - if ( !ulIsAbsolutePathName( path.c_str() ) ) { - SGPath tmp = fg_root; - tmp.append(modelpath.str()); - modelpath = tmp; - } - - // Check for an XML wrapper - if (modelpath.str().substr(modelpath.str().size() - 4, 4) == ".xml") { - readProperties(modelpath.str(), &props); - if (props.hasValue("/path")) { - modelpath = modelpath.dir(); - modelpath.append(props.getStringValue("/path")); - } else { - if (model == 0) - model = new ssgBranch; + osg::Image* image; + if (options) + image = osgDB::readImageFile(path, options); + else + image = osgDB::readImageFile(path); + osg::ref_ptr texture = new osg::Texture2D; + texture->setImage(image); + if (staticTexture) + texture->setDataVariance(osg::Object::STATIC); + if (wrapu) + texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); + else + texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); + if (wrapv) + texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); + else + texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP); + + if (image) { + int s = image->s(); + int t = image->t(); + + if (s <= t && 32 <= s) { + SGSceneFeatures::instance()->setTextureCompression(texture.get()); + } else if (t < s && 32 <= t) { + SGSceneFeatures::instance()->setTextureCompression(texture.get()); } } - // Assume that textures are in - // the same location as the XML file. - if (model == 0) { - ssgTexturePath((char *)modelpath.dir().c_str()); - model = (ssgBranch *)ssgLoad((char *)modelpath.c_str()); - if (model == 0) - throw sg_exception("Failed to load 3D model"); + // Make sure the texture is shared if we already have the same texture + // somewhere ... + { + osg::ref_ptr tmpNode = new osg::Node; + osg::StateSet* stateSet = tmpNode->getOrCreateStateSet(); + stateSet->setTextureAttribute(0, texture.get()); + + // OSGFIXME: don't forget that mutex here + osgDB::Registry* registry = osgDB::Registry::instance(); + registry->getSharedStateManager()->share(tmpNode.get(), 0); + + // should be the same, but be paranoid ... + stateSet = tmpNode->getStateSet(); + osg::StateAttribute* stateAttr; + stateAttr = stateSet->getTextureAttribute(0, osg::StateAttribute::TEXTURE); + osg::Texture2D* texture2D = dynamic_cast(stateAttr); + if (texture2D) + texture = texture2D; } - // Set up the alignment node - ssgTransform * alignmainmodel = new ssgTransform; - alignmainmodel->addKid(model); - sgMat4 res_matrix; - sgMakeOffsetsMatrix(&res_matrix, - props.getFloatValue("/offsets/heading-deg", 0.0), - props.getFloatValue("/offsets/roll-deg", 0.0), - props.getFloatValue("/offsets/pitch-deg", 0.0), - props.getFloatValue("/offsets/x-m", 0.0), - props.getFloatValue("/offsets/y-m", 0.0), - props.getFloatValue("/offsets/z-m", 0.0)); - alignmainmodel->setTransform(res_matrix); - - unsigned int i; - - // Load animations - vector animation_nodes = props.getChildren("animation"); - for (i = 0; i < animation_nodes.size(); i++) { - const char * name = animation_nodes[i]->getStringValue("name", 0); - vector name_nodes = - animation_nodes[i]->getChildren("object-name"); - sgMakeAnimation( model, name, name_nodes, prop_root, animation_nodes[i], - sim_time_sec); - } - - // Load sub-models - vector model_nodes = props.getChildren("model"); - for (i = 0; i < model_nodes.size(); i++) { - SGPropertyNode_ptr node = model_nodes[i]; - ssgTransform * align = new ssgTransform; - sgMat4 res_matrix; - sgMakeOffsetsMatrix(&res_matrix, - node->getFloatValue("offsets/heading-deg", 0.0), - node->getFloatValue("offsets/roll-deg", 0.0), - node->getFloatValue("offsets/pitch-deg", 0.0), - node->getFloatValue("offsets/x-m", 0.0), - node->getFloatValue("offsets/y-m", 0.0), - node->getFloatValue("offsets/z-m", 0.0)); - align->setTransform(res_matrix); - - ssgBranch * kid = sgLoad3DModel( fg_root, node->getStringValue("path"), - prop_root, sim_time_sec ); - align->addKid(kid); - model->addKid(align); - } - - return alignmainmodel; + return texture.release(); } - // end of model.cxx