Beispiel #1
0
void EEPFILE::eeLoadModelName(uint8_t id,char*buf,uint8_t len)
{
  if(id<MAX_MODELS)
  {
    //eeprom_read_block(buf,(void*)modelEeOfs(id),sizeof(g_model.name));

    memset(buf,' ',len);
    *buf='0'+(id+1)/10; buf++;
    *buf='0'+(id+1)%10; buf++;
    *buf=':';           buf++;buf++;

    if(!eeModelExists(id))  // make sure we don't add junk
    {
        *buf=0; //terminate str
        return;
    }

    theFile->openRd(FILE_MODEL(id));
    uint16_t res = theFile->readRlc((uint8_t*)buf,sizeof(ModelData().name));
    if(res == sizeof(ModelData().name) )
    {
      //buf+=len-5;
      for(int i=0; i<(len-4); i++)
      {
          if(*buf==0) *buf=' ';
          buf++;
      }
      *buf=0;buf--;
      uint16_t sz=theFile->size(FILE_MODEL(id));
      while(sz){ --buf; *buf='0'+sz%10; sz/=10;}
    }
  }
}
Beispiel #2
0
ModelData DiscreteObject::getModel(){
    return ModelData(B, A, k, noiseRatio);
}
Beispiel #3
0
World::World(WindowFramework* windowFrameworkPtr)
   : m_windowFrameworkPtr(windowFrameworkPtr)
   {
   // preconditions
   if(m_windowFrameworkPtr == NULL)
      {
      nout << "ERROR: parameter windowFrameworkPtr cannot be NULL." << endl;
      return;
      }

   // This code puts the standard title and instruction text on screen
   COnscreenText title("title", COnscreenText::TS_plain);
   title.set_text("Panda3D: Tutorial - Joint Manipulation");
   title.set_fg(Colorf(1,1,1,1));
   title.set_pos(LVecBase2f(0.7, -0.95));
   title.set_scale(0.07);
   title.reparent_to(m_windowFrameworkPtr->get_aspect_2d());
   m_titleNp = title.generate();
   m_esckeyTextNp   = gen_label_text("ESC: Quit"      , 0);
   m_onekeyTextNp   = gen_label_text("[1]: Teapot"    , 1);
   m_twokeyTextNp   = gen_label_text("[2]: Candy cane", 2);
   m_threekeyTextNp = gen_label_text("[3]: Banana"    , 3);
   m_fourkeyTextNp  = gen_label_text("[4]: Sword"     , 4);

   // setup key input
   m_windowFrameworkPtr->enable_keyboard();
   m_windowFrameworkPtr->get_panda_framework()->define_key("escape", "Exit"     , sys_exit      , NULL);
   m_windowFrameworkPtr->get_panda_framework()->define_key("1"     , "Teapot"   , call_set_object<M_teapot    >, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("2"     , "CandyCane", call_set_object<M_candy_cane>, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("3"     , "Banana"   , call_set_object<M_banana    >, this);
   m_windowFrameworkPtr->get_panda_framework()->define_key("4"     , "Sword"    , call_set_object<M_sword     >, this);

   // Disable mouse-based camera-control
   // Note: disable by default in C++

   // Position the camera
   m_windowFrameworkPtr->get_camera_group().set_pos(0,-15, 2);

   // Load our animated character
   // Note: File eve_walk.egg is broken!
   //       The name of the animation is case sensitive and at line 13 of file
   //       eve_walk.egg you should read `Eve' instead of `eve'. You need to
   //       correct this in order to bind the animation automatically using
   //       auto_bind() or WindowFramework::loop_animations(). Or you can use
   //       PartGroup::HMF_ok_wrong_root_name to ask auto_bind() to be more
   //       forgiving.
   CActor::AnimMap eveAnims;
   eveAnims["../models/eve_walk"].push_back("walk");
   m_eve.load_actor(m_windowFrameworkPtr,
                    "../models/eve",
                    &eveAnims,
                    PartGroup::HMF_ok_wrong_root_name);

   // Put it in the scene
   NodePath renderNp = m_windowFrameworkPtr->get_render();
   m_eve.reparent_to(renderNp);

   // Now we use control_joint to get a NodePath that's in control of her neck
   // This must be done before any animations are played
   m_eveNeckNp = m_eve.control_joint("Neck");

   // We now play an animation. An animation must be played, or at least posed
   // for the nodepath we just got from control_joint to actually effect the model
   m_eve.find_anim("walk")->set_play_rate(2);
   m_eve.loop("walk", true);

   // Now we add a task that will take care of turning the head
   PT(GenericAsyncTask) turnHeadTask = new GenericAsyncTask("turnHead", call_turn_head, this);
   if(turnHeadTask != NULL)
      {
      AsyncTaskManager::get_global_ptr()->add(turnHeadTask);
      }

   // Now we will expose the joint the hand joint. ExposeJoint allows us to
   // get the position of a joint while it is animating. This is different than
   // control_joint which stops that joint from animating but lets us move it.
   // This is particularly useful for putting an object (like a weapon) in an
   // actor's hand
   m_eveRightHandNp = m_eve.expose_joint("RightHand");

   // This is a table with models, positions, rotations, and scales of objects to
   // be attached to our exposed joint. These are stock models and so they needed
   // to be repositioned to look right.
   vector<ModelData> positions(M_models);
   positions[M_teapot    ] = ModelData("../models/teapot"   , LVecBase3f(0.00,-0.66,-0.95), LVecBase3f(90,  0,90), 0.40);
   positions[M_candy_cane] = ModelData("../models/candycane", LVecBase3f(0.15,-0.99,-0.22), LVecBase3f(90,  0,90), 1.00);
   positions[M_banana    ] = ModelData("../models/banana"   , LVecBase3f(0.08,-0.10, 0.09), LVecBase3f( 0,-90, 0), 1.75);
   positions[M_sword     ] = ModelData("../models/sword"    , LVecBase3f(0.11, 0.19, 0.06), LVecBase3f( 0,  0,90), 1.00);
   // A list that will store our models objects
   m_modelsNp.reserve(M_models);
   NodePath modelsNp = m_windowFrameworkPtr->get_panda_framework()->get_models();
   for(vector<ModelData>::iterator i = positions.begin(); i < positions.end(); ++i)
      {
      // Load the model
      NodePath np = m_windowFrameworkPtr->load_model(modelsNp, i->m_filename);
      // Position it
      np.set_pos(i->m_pos);
      // Rotate it
      np.set_hpr(i->m_hpr);
      // Scale it
      np.set_scale(i->m_scale);
      // Reparent the model to the exposed joint. That way when the joint moves,
      // the model we just loaded will move with it.
      np.reparent_to(m_eveRightHandNp);
      // Add it to our models list
      m_modelsNp.push_back(np);
      }

   // Make object 0 the first shown
   set_object(M_teapot);
   // Put in some default lighting
   setup_lights();
   }
ModelData ModelLoader::Load(const std::vector<std::uint8_t>& fileData, const char* type)
{
    Assimp::Importer importer;
    const aiScene* scene = importer.ReadFileFromMemory(
                                        fileData.data(),
                                        fileData.size(),
                                        aiProcess_Triangulate |
                                        aiProcess_FlipUVs |
                                        aiProcess_GenNormals |
                                        aiProcess_CalcTangentSpace |
                                        aiProcess_SortByPType |
                                        aiProcess_JoinIdenticalVertices |
                                        aiProcess_ImproveCacheLocality,
                                        type);

    if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
        return ModelData();

    // Used for creating the boundingBox
    glm::vec3 minPoint, maxPoint;

    auto processMesh = [&minPoint, &maxPoint](aiMesh* mesh, const aiScene* scene) -> MeshData
    {
        (void) scene;

        MeshData mData;

        for (std::uint32_t i = 0; i < mesh->mNumVertices; ++i)
        {
            VertexData vertexData;

            // Vertices
            const aiVector3D& vert = mesh->mVertices[i];
            vertexData.vx = vert.x;
            vertexData.vy = vert.y;
            vertexData.vz = vert.z;

            // Normals
            const aiVector3D& norm = mesh->mNormals[i];
            vertexData.nx = norm.x;
            vertexData.ny = norm.y;
            vertexData.nz = norm.z;

            if(mesh->HasTangentsAndBitangents())
            {
                // Tangents
                const aiVector3D& tan = mesh->mTangents[i];
                vertexData.tnx = tan.x;
                vertexData.tny = tan.y;
                vertexData.tnz = tan.z;
            }
            // TODO: think if we need the 'else' part
            //else {}

            // Texture coordinates
            if (mesh->mTextureCoords[0])
            {
                const aiVector3D& texCoord = mesh->mTextureCoords[0][i];
                vertexData.tx = texCoord.x;
                vertexData.ty = texCoord.y;
            }
            else
            {
                vertexData.tx = 0;
                vertexData.ty = 0;
            }

            // AABB minPoint
            if (vert.x < minPoint.x)
                minPoint.x = vert.x;
            if (vert.y < minPoint.y)
                minPoint.y = vert.y;
            if (vert.z < minPoint.z)
                minPoint.z = vert.z;
            // AABB maxPoint
            if (vert.x > maxPoint.x)
                maxPoint.x = vert.x;
            if (vert.y > maxPoint.y)
                maxPoint.y = vert.y;
            if (vert.z > maxPoint.z)
                maxPoint.z = vert.z;

            // Material index
            mData.meshIndex = mesh->mMaterialIndex;

            mData.data.push_back(vertexData);
        }

        // Indices
        for (std::uint32_t i = 0; i < mesh->mNumFaces; ++i)
        {
            aiFace face = mesh->mFaces[i];
            for (std::uint32_t j = 0; j < face.mNumIndices; ++j)
                mData.indices.push_back(face.mIndices[j]);
        }

        // Material
        if (scene->HasMaterials())
        {
            aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
            if (material)
            {
                auto texTypes = {aiTextureType_DIFFUSE, aiTextureType_SPECULAR, aiTextureType_NORMALS, aiTextureType_NONE};
                for (auto type : texTypes)
                {
                    std::uint32_t texCount = material->GetTextureCount(type);
                    for (std::uint32_t i = 0; i < texCount; ++i)
                    {
                        aiString str;
                        material->GetTexture(type, i, &str);
                        // TODO
                    }
                }
            }
        }

        return mData;
    };

    std::function<ModelData(aiNode*, const aiScene*)> processNode =
    [&processMesh, &processNode](aiNode* node, const aiScene* scene) -> ModelData
    {
        ModelData model;

        // Process all the node's meshes
        for (std::uint32_t i = 0; i < node->mNumMeshes; ++i)
        {
            aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
            model.meshes.push_back(processMesh(mesh, scene));
        }

        // Same for its children
        for (std::uint32_t i = 0; i < node->mNumChildren; ++i)
        {
            ModelData childModel = processNode(node->mChildren[i], scene);
            for (auto& mesh : childModel.meshes)
                model.meshes.push_back(std::move(mesh));
        }

        return model;
    };

    ModelData model = processNode(scene->mRootNode, scene);
    model.boundingBox = AABB(minPoint, maxPoint);
    return model;
}
ModelData ModelIdentification::identify(double w, double u, double y){
    // stałe pierwszego zbiornika:
    double A1 = 0.7329;
    double H1 = 4.6526;
    double kv1 = 0.2113;

    // stałe drugiego zbiornika:
    double tgalfa2 = 4.2687;
    double kv2 = 0.4336;

    // punkt pracy:
    // pierwszego zbiornika:

    // 1. punktu pracy pierwszego zbiornika nie można dokłądnie określić.
    // poprawne wyznaczenie punktu pracy jest szczegulnie ważne w chwili przelania.
    // orientacyjnie przyjmujemy punkt pracy do którego dążymy.
    //double h1 = pow(2, w/kv1);
    // 2. drobna symulacja ktora jest niżej
    // można sobie na nią pozwolić ponieważ w stanie ustalonym wszystkie błędy i tak znikną
    double h1 = temp;
    // 3. próba średniej ważonej obu pomysłów:
    //double w1 = 100;
    //double w2 = sampleTime; // waga zależna od czasu próbkowania:
    //double h1 = (temp * w1 + pow(2, w/kv1) * w2) / (w1 + w2);

    // drugiego zbiornika:
        // punkt pracy drugiego zbiornika to dokładnie jego wypływ.
    double q20 = y;

    //parametry pierwszego zbiornika:
    double b10;
    double a11;
    double op1;

    // obliczenie wypływu z pierwszego zbiornika na podstawie punktu pracy:
    double q10 = sqrt(h1) * kv1;

    // sprawdzenie czy zbiornika jest pełny:
    bool fullTank = ( h1 >= H1 );

    if (!fullTank) {
        // dla niepelnego zbiornika:

        // transmitancja ciagla pierwszego zbiornika:
        // K(s) = k / (1 + sT)
        double T1 = A1 * 2 * q10 / (kv1 * kv1);
        double k1 = 1;

        // transmitancja dyskretna pierwszego zbiornika:
        // H(z^-1) = b0 / (1 + a1*(z^-1)
        a11 = - pow(M_E, - (sampleTime / T1));
        b10 = k1 * (1 + a11);
        op1 = 1;
    } else {
        // dla pelnego zbiornika:

        // transmitancja ciagla pierwszego zbiornika:
        // K(s) = k / (1 + sT)
        // k1 = 1;
        // T1 = 0;
        // K(s) = 1;

        // transmitancja dyskretna pierwszego zbiornika:
        // H(z^-1) = b0 / (1 + a1*(z^-1))
        a11 = 0;
        b10 = 1;
        op1 = 0;
        // H(z^-1) = 1;
    }

    // aktualizacja punktu pracy:
    h1 = h1 + (u - q10)/A1 * sampleTime;
    // sprawdzenie przepełnienia i pustego:
    h1 = h1 < 0 ? 0 : (h1 > H1 ? H1 : h1);
    // aktualizacja zmiennej prywatnej:
    temp = h1;

    // transmitancja ciagla drugiego zbiornika w punkcie pracy:
    // K(s) = k / (1 + sT)
    double T2 = ( 2 * M_PI * pow(q20,5) ) / ( tgalfa2 * tgalfa2 * pow(kv2,6) );
    double k2 = 1;

    // transmitancja dyskretna drugiego zbiornika w punkcie pracy:
    // H(z^-1) = b0 / (1 + a1*(z^-1))
    double a21 = - pow(M_E, - (sampleTime / T2));
    double b20 = k2 * (1 + a21);
    double op2 = 1;

    // transmitancja końcowa:
    double b0 = b10 * b20;
    double a0 = 1;
    double a1 = a11 + a21;
    double a2 = a11 * a21;
    double op = op1 + op2;

    std::vector<double> B;
    std::vector<double> A;

    B.push_back(b0);
    A.push_back(a0);
    A.push_back(a1);
    A.push_back(a2);

    //std::cout << ModelData(B, A, op) << "\n";

    return ModelData(B, A, op);
    // mamy model drugiego rzędu z opóźnieniem równym 2
    // lub model pierwszego rzędu z opóźnieniem równym 1
    // więc w sumie to jest to niestacjonarność...
}
Beispiel #6
0
void CBloodFlower::TurnEffectsOff(u32 effect, CStateManager& mgr) {
  ModelData()->AnimationData()->SetParticleEffectState(sFireEffects[effect], false, mgr);
}