- 积分
- 55
- 帖子
- 26
- 主题
- 10
- 精华
- 0
- 最后登录
- 2018-1-4
- 在线时间
- 22 小时
- 私信
|
发表时间 : 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;
}
|
|