我要发帖 回复

正式会员

10

主题

55

积分

0

专家分

:

私信
发表时间 : 2011-11-23 11:18:36 | 浏览 : 2727    评论 : 4
这是我用vp中的一个例子改的,源于vp_flight_path这个例子
我想根据大模型运动留下轨迹,想实现在当DOF结点运动 时,也留下轨迹,如何做,请看代码:
别的地方我都没改,红色部分是我新增的

#include <vuAllocArray.h>
#include <vuAllocTracer.h>
#include <vrGeometry.h>
#include <vrLight.h>
#include <vrMode.h>
#include <vsGeometry.h>
#include <vsRenderStrategy.h>
#include <vpApp.h>
#include <vpObject.h>
#include <vrMaterial.h>
#include "vsDOF.h"
#include <iostream>
using std::cout;
using std::endl;
// global defines for path definition
int s_pathSegments = 1000;
double s_pathSegmentLength = 60.0;
float s_pathWidth = 5.0f;
// track memory leaks
vuAllocTracer allocTracer;
// the main application class.  Note that we must derive from
// vpPageable::Subscriber here so that we can inherit the load complete
// notify method
class myApp : public vpApp, public vpPageable::Subscriber {
public:
    /**
     * Constructor
     */
    myApp()
    {
}
    /**
     * Destructor
     */
    ~myApp()
    {
        // unreference member variables which cache Vega Prime class instances
        m_pathGeometry->setRenderStrategy(NULL);
  m_pathGeometry->unref();
  m_pathNode->unref();
  m_pathFrameGeometry->unref();
  m_f16->unref();
    }
   
    /**
     * Configure my app
     */
    int configure() {
        // pre-configuration

        // configure vega prime system first
        vpApp::configure();

        // post-configuration
        // Increase the reference count by one for all member variables which
        // cache the Vega Prime class instances.
        //
        // All VSG/Vega Prime class instances are referenced counted.
        // The initial reference count is 0 after the instance is created.
        // When the reference count is smaller or equal to 0 in unref(),
        // the instance will be deleted automatically. Increasing reference
        // count here for all member variables will guarantee that they will
        // not be deleted until myApp is deleted.
  // get a pointer to the f16 object
  m_f16 = vpObject::find("f16");
        assert(m_f16);
  m_f16->ref();

//大的DOF前臂
  m_FrontDof=(vsDOF*)m_f16->find_named("LLZ1");


        // create the path geometry.  The geometry will be a yellow
        // semi-transparent tri strip.
        m_pathGeometry = new vrGeometry();
        m_pathGeometry->setPrimitive(vrGeometry::PRIMITIVE_TRIANGLE_STRIP);
        m_pathGeometry->setNumPrimitives(1);
        int *length = vuAllocArray<int>::malloc(1);
        length[0] = 2;
        m_pathGeometry->setPrimitiveLengths(length);
        vuVec4<float> *color = vuAllocArray<vuVec4<float> >::malloc(1);
        color[0].set(1.0f, 1.0f, 0.0f, 0.5f);
        m_pathGeometry->setColors(color, vrGeometryBase::BINDING_OVERALL);
        vuVec3<float> *vertex = vuAllocArray<
            vuVec3<float> >::malloc(s_pathSegments);
        m_pathGeometry->setVertices(vertex);
        m_pathGeometry->ref();
        // create the path state
        vrState *state = new vrState();
        // enable transparency
        vrAlphaBlend::Element alphaBlendElement;
        alphaBlendElement.m_enable = true;
        alphaBlendElement.m_src = vrAlphaBlend::MODE_SRC_ALPHA;
        alphaBlendElement.m_dst = vrAlphaBlend::MODE_INVERSE_SRC_ALPHA;
        //state->setElement(vrAlphaBlend::Element::Id, &alphaBlendElement);
        // disable back face culling so we can see the path from both sides
        vrPolygon::Element polygonElement;
        polygonElement.m_enableCullFace = false;
        state->setElement(vrPolygon::Element::Id, &polygonElement);
        // disable lighting so the fragment color will only be based upon our
        // geometry color
        vrLight::Element lightElement;
        lightElement.m_enable = false;
        state->setElement(vrLight::Element::Id, &lightElement);
        // create a geometry node for the path and add it to the scene graph
        m_pathNode = new vsGeometry();
        m_pathNode->setGeometry(m_pathGeometry);
        m_pathNode->setState(state);
        m_pathNode->ref();
        vpScene *scene = *vpScene::begin();
        assert(scene);
        scene->push_back_child(m_pathNode);
        // create a render strategy for our path geometry and multi-buffer the
        // primitive lengths and vertex attribute arrays
        m_pathFrameGeometry = new vsRenderStrategyFrameGeometry(m_pathGeometry,
            vsRenderStrategyFrameGeometry::ATTRIBUTE_PRIMITIVE_LENGTHS |
            vsRenderStrategyFrameGeometry::ATTRIBUTE_VERTICES);
        m_pathFrameGeometry->ref();
        m_pathGeometry->setRenderStrategy(m_pathFrameGeometry);
        // set the initial position of the f16 and the path
        updatePosition();
        
        return vsgu::SUCCESS;
    }
    /**
     * Override endFrame so we'll get called every frame and we can perform
     * our updates
     */
    virtual int endFrame(void) const
    {
        // update the position of the f16 and update the path
        const_cast<myApp *>(this)->updatePosition();
        // let the base class do it's work
        return vpApp::endFrame();
    }
private:
    /**
     * Update the position of the f16 and the path
  更新飞机位置
     */
    void updatePosition()
    {
         //fly the f16 in a circle, gradually increasing the radius and height
//在每一帧不断改变整体模型的位置
        float s, c;
        static float height = 10.0f, radius =115.0f, angle = 0.0f;
        angle += (float) 18.0f * vpKernel::instance()->getSimulationDeltaTime();
        if (angle > 360) angle -= 360.0f;
        vuSinCos(angle, &s, &c);
  
        m_f16->setTranslate(2500.0 + c * radius, 2500.0 + s * radius, height);
        m_f16->setRotate(angle, 0.0f, 0.0f);
        height += 0.05f;
        radius += 0.05f;

  
//使用updatePath函数,根据整体模型m_f16的位置信息,画出整体模型的运动轨迹,
        //updatePath(m_f16);//这个更新整个飞机的位置用的,用于画整体的运动轨迹,所以我把它注销了


  //以下这段是我新增内容
  
  //新需求:在整体大模型m_f16中有一个DOF结点,当这个DOF结点运动时,画出这个DOF结点的运动轨迹
  //我的想法是:把这个DOF结点填入这个updatepath函数中应该可以实现,可是却遇到了问题

  //这里我让这个DOF结点运动,然后把这个DOF结点转化为vpObject类型,然后填入updatepath()函数中,却画不出这个DOF结点的运动轨迹
  //为什么呢?请高手指教,非常感谢,急需!
  m_FrontDof->setTranslateY(0.01, true);
  //编译时,下边这句会提示:无法从vsDOF*转化为vpObject*,如何办?
  vpObject* tmpObj_m_FrontDof=static_cast<vpObject*>(m_FrontDof);
  updatePath(tmpObj_m_FrontDof);


  //我的别的想法:修改updatepath函数,但是关键是这个updatepath函数只接受vpObject*类型的参数,没法把参数改为vsNode*类型,因为在update()函数中
  //vsNode*类型的实例没有getMatrixAffine()方法
  //请高手给俺指条明路,感谢!

  
  //以上这段是我新增内容

    }
    /**
     * update the path
     */
    void updatePath(vpObject *src)
    {
        // update the last two vertices in the path w/ the current object
        // position
        int *length = m_pathGeometry->getPrimitiveLengths();
        vuVec3<float> *vertex = m_pathGeometry->getVertices();
        vuVec3<float> v1(-s_pathWidth, -6.0f, 0.0f);
        vuVec3<float> v2(s_pathWidth, -6.0f, 0.0f);
        vuMatrix<float> mf;
        const vuMatrix<double> &md = src->getMatrixAffine().getMatrix();
        vuMatrixConvert(&mf, md);
        mf.transformPoint(&v1);
        vertex[length[0] - 2] = v1;
        mf.transformPoint(&v2);
        vertex[length[0] - 1] = v2;
        // when the length of our current segment exceeds the desired segment
        // length, extend the path
        static vuVec3<double> lastPos;
        vuVec3<double> pos(md[3][0], md[3][1], md[3][2]);
        if (pos.distance(lastPos) > s_pathSegmentLength) {
            // if we haven't reached the maximum path length yet, add another
            // pair of points to the path by extending the length of the
            // tri strip
            if (length[0] + 2 < s_pathSegments) {
                vertex[length[0]] = vertex[length[0] - 2];
                length[0]++;
                vertex[length[0]] = vertex[length[0] - 2];
                length[0]++;
                m_pathGeometry->setPrimitiveLengths(length);
            }
            // otherwise, shift all the vertices in the array so that we drop
            // the last segment
            else {
                int num = length[0] - 2;
                for (int i=0;i<num;i+=2) {
                    vertex = vertex[i + 2];
                    vertex[i + 1] = vertex[i + 3];
                }
                // remove the first ghost object from the scene
                vpScene *scene = *vpScene::begin();
                scene->removeChild(*m_ghosts.begin());
                m_ghosts.erase(m_ghosts.begin());
            }
            // make a new ghost object which indicates the position and
            // orientation of the plane at this way point
            makeGhost(src);
            // save our current position
            lastPos = pos;
        }
        // reset the vertex pointer so the geometry "knows" that it's been
        // changed.  This will force the bounding box for the geometry to
        // get updated
        m_pathGeometry->setVertices(vertex);
        // set the DIRTY_BOUNDS flag on the path node to force an update
        // of the node bounding sphere.  If we don't do this the bounding
        // sphere will not reflect the true size of the geometry beneath
        // it and it's possible that we could get incorrectly culled from
        // the scene.
        m_pathNode->setDirtyMask(vsNode::DIRTY_BOUNDS, vsNode::BITOP_OR);
        // update the frame geometry so our changes get propigated
        if (m_pathFrameGeometry != NULL) m_pathFrameGeometry->update();
    }
    /**
     * make a copy of 'src' and add it to the scene at the same location */
     
    void makeGhost(vpObject *src)
    {
        // create a new object which is a copy of the source
        vpObject *object = new vpObject();
        object->addSubscriber(vpPageable::EVENT_LOAD_COMPLETE, this);
        //NOTE that we are going to modify material on the
        //ghost objects. Therefore, we need to copy material by VALUE.
        vsgu::Options opt;
        opt[vsRepresentationBase::getOptionIndex()] |= vsRepresentationBase::OPTION_STATE_BY_VALUE;
        
        object->setCopySourceOptions(opt);
        object->setCopySource(src);
        object->autoPage();
        
        // the pageSynchronous call only guarantees that the geometry is
        // loaded in the current thread, however, due to other constraits such
        // as waiting for textures to finish subloading, synchronization w/
        // distributed rendering slaves, etc., there is no guarantee that the
        // loading process is actually "complete" here.  As a result, any
        // immediate post processing of geometry needs to wait.  By installing
        // a load complete subscriber, we are assured that everything is
        // finished and it is safe to post process the geometry.  Note,
        // however, that it is ok to do things to the object itself (e.g. set
        // the position, add it to the scene, etc. as shown below), we just
        // need to hold off on any post processing of the object's geometry.
        // put the object at the current position of the source
        double x, y, z, h, p, r;
        src->getTranslate(&x, &y, &z);
        object->setTranslate(x, y, z);
        src->getRotate(&h, &p, &r);
        object->setRotate(h, p, r);
        src->getScale(&x, &y, &z);
        object->setScale(x, y, z);
        // add the object to the scene
        vpScene *scene = *vpScene::begin();
        scene->addChild(object);
        // add the object to our list
        m_ghosts.push_back(object);
    }

    /**
     * inherited load complete notification method to post process the
     * object's geometry.
     */
    virtual void notify(vpPageable::Event, const vpPageable *publisher)
    {
        // make the object semi-transparent.  The value passed into the
        // constuctor is the alpha value we want things set to which we're
        // treating as user data here.  Notice here that our traversal is
        // only stopping on vsGeometry instances, so if for example the
        // geometry had light points we'd need to do another function for that.
        vsTraversalUser<float, vsTraversalLookUpNodeId> trav(0.2f);
        trav.addPreVisit(vsGeometry::getStaticNodeId(),
   this, &myApp::travFuncGeometry);
        trav.visit(static_cast<const vpObject *>(publisher)->getRootNode());
    }
    /**
     * traversal function for ghosting which makes geometry transparent
     */
    vsTraversal::Result travFuncGeometry(vsNode *node, float alpha)
    {
        // make sure transparency is enabled on the state otherwise it won't
        // matter what we set the alpha values too
  vrState *state = static_cast<vsGeometry *>(node)->getState();
        vsgu::Options options;
        vrState* newState = new vrState;

        vsgu::copy<vrState>(newState,state,options);
        vrAlphaBlend::Element alphaBlendElement;
        alphaBlendElement.m_enable = true;
        alphaBlendElement.m_src = vrAlphaBlend::MODE_SRC_ALPHA;
        alphaBlendElement.m_dst = vrAlphaBlend::MODE_INVERSE_SRC_ALPHA;
        //In VSG 2.0, color tracking is no longer used.
        //Use Material to provide vertex alpha
        const vrMaterial::Element* matEl = vrGetElement(newState,vrMaterial::Element::Id);
        float r,g,b,a;
        vrMaterial* mtl = matEl->m_material;
        if(mtl)
        {
            mtl->getColor(vrMaterial::COLOR_DIFFUSE,&r,&g,&b,&a);
            mtl->setColor(vrMaterial::COLOR_DIFFUSE,r,g,b,alpha);
        }
        //newState->setElement(vrAlphaBlend::Element::Id, &alphaBlendElement);
        static_cast<vsGeometry *>(node)->setState(newState);
        return vsTraversal::RESULT_CONTINUE;
    }
    // a vector containing the ghost objects we've added to the scene
    vuVector<vpObject *> m_ghosts;
// our path geometry
vrGeometry *m_pathGeometry;
// our path node
vsGeometry *m_pathNode;
// our path frame geometry
vsRenderStrategyFrameGeometry *m_pathFrameGeometry;
// the f16 object
vpObject *m_f16;

vsDOF * m_FrontDof;

  

};
int main(int argc, char *argv[])
{
    // initialize vega prime
    vp::initialize(argc, argv);
    // create my app instance
    myApp *app = new myApp;
    // load acf file
    if (argc <= 1)
        app->define("drawAngle.acf");
    else
        app->define(argv[1]);
    // configure my app
    app->configure();
    // runtime loop
    app->run();
    // unref my app instance
    app->unref();
    // shutdown vega prime
    vp::shutdown();
    return 0;   
}



最近VR访客

cyscsharp 评论于2011-11-23 14:24:20
为何没人回呢?在线。。。。。。等。。。。。。待中。。。。。。。
single010203专家组 评论于2011-11-23 22:01:22
cyscsharp 发表于 2011-11-23 02:24 PM
为何没人回呢?在线。。。。。。等。。。。。。待中。。。。。。。

很长看上去很累啊,,帮你顶顶,请问你做过dof节点的飞机发射导弹的程序吗?我做了一个,但是发射的时候导弹不见了,求助啊,急死了,
chanjoy1988 评论于2012-2-3 10:28:08
我想让飞机沿固定的路径运动,可是不晓得怎样制作路径文件
angelajer 评论于2012-2-27 10:11:41
看了帮助文档,还是不太会使用pathtool

手机版|VR开发网 统计 津ICP备18009691号
网安备12019202000257

GMT+8, 2021-1-23 08:10 PM

返回顶部