コード例 #1
0
ファイル: terraingrid.cpp プロジェクト: EmperorArthur/openmw
osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter)
{
    if (chunkSize * mNumSplits > 1.f)
    {
        // keep splitting
        osg::ref_ptr<osg::Group> group (new osg::Group);
        if (parent)
            parent->addChild(group);

        float newChunkSize = chunkSize/2.f;
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f));
        return group;
    }
    else
    {
        osg::ref_ptr<osg::Node> node = mChunkManager->getChunk(chunkSize, chunkCenter, 0, 0);
        if (!node)
            return NULL;
        if (parent)
            parent->addChild(node);

        return node;
    }
}
コード例 #2
0
Terrain* TerrainGenerator::getTerrain()
{
    if (!_terrain || _isDirty) {
        buildTerrain();
    }
    return _terrain;
}
コード例 #3
0
void TerrainGrid::loadCell(int x, int y)
{
    if (mGrid.find(std::make_pair(x, y)) != mGrid.end())
        return; // already loaded

    // try to get it from the cache
    osg::ref_ptr<osg::Node> terrainNode;
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex);
        Grid::const_iterator found = mGridCache.find(std::make_pair(x,y));
        if (found != mGridCache.end())
        {
            terrainNode = found->second;
            if (!terrainNode)
                return; // no terrain defined
        }
    }

    // didn't find in cache, build it
    if (!terrainNode)
    {
        osg::Vec2f center(x+0.5f, y+0.5f);
        terrainNode = buildTerrain(NULL, 1.f, center);
        if (!terrainNode)
            return; // no terrain defined
    }

    mTerrainRoot->addChild(terrainNode);

    mGrid[std::make_pair(x,y)] = terrainNode;
}
コード例 #4
0
osg::ref_ptr<osg::Node> TerrainGrid::cacheCell(int x, int y)
{
    {
        OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex);
        Grid::iterator found = mGridCache.find(std::make_pair(x,y));
        if (found != mGridCache.end())
            return found->second;
    }
    osg::ref_ptr<osg::Node> node = buildTerrain(NULL, 1.f, osg::Vec2f(x+0.5, y+0.5));

    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mGridCacheMutex);
    mGridCache.insert(std::make_pair(std::make_pair(x,y), node));
    return node;
}
コード例 #5
0
ファイル: terraingrid.cpp プロジェクト: EmperorArthur/openmw
void TerrainGrid::loadCell(int x, int y)
{
    if (mGrid.find(std::make_pair(x, y)) != mGrid.end())
        return; // already loaded

    osg::Vec2f center(x+0.5f, y+0.5f);
    osg::ref_ptr<osg::Node> terrainNode = buildTerrain(NULL, 1.f, center);
    if (!terrainNode)
        return; // no terrain defined

    mTerrainRoot->addChild(terrainNode);

    mGrid[std::make_pair(x,y)] = terrainNode;
}
コード例 #6
0
ファイル: PlatformDemoState.cpp プロジェクト: fallahn/xygine
PlatformDemoState::PlatformDemoState(xy::StateStack& stateStack, Context context)
    : State         (stateStack, context),
    m_messageBus    (context.appInstance.getMessageBus()),
    m_scene         (m_messageBus),
    m_physWorld     (m_messageBus),
    m_meshRenderer  ({ context.appInstance.getVideoSettings().VideoMode.width, context.appInstance.getVideoSettings().VideoMode.height }, m_scene)
{
    launchLoadingScreen();
    xy::Stats::clear();
    m_physWorld.setGravity({ 0.f, 1180.f });
    m_physWorld.setPixelScale(120.f);

    m_scene.setView(context.defaultView);
    m_scene.setAmbientColour({ 76, 70, 72 });
    m_scene.getSkyLight().setIntensity(0.5f);
    m_scene.getSkyLight().setDiffuseColour({ 255, 255, 200 });
    m_scene.getSkyLight().setSpecularColour({ 120, 255, 58 });
    m_scene.getSkyLight().setDirection({ 0.2f, 0.4f, -0.4f });

    m_meshRenderer.setView(context.defaultView);

    cacheMeshes();
    buildTerrain();
    buildPhysics();

    addItems();
    addPlayer();

    auto e = xy::Entity::create(m_messageBus);
    auto md = m_meshRenderer.createDrawable(m_messageBus);
    //md->enableWater(true);
    e->addComponent(md);
    m_scene.addEntity(e, xy::Scene::Layer::FrontFront);

    REPORT("Q", "Show Debug");
    xy::App::setMouseCursorVisible(true);

    quitLoadingScreen();
}
コード例 #7
0
ファイル: terraingrid.cpp プロジェクト: ChairGraveyard/TES3MP
void TerrainGrid::loadCell(int x, int y)
{
    if (mGrid.find(std::make_pair(x, y)) != mGrid.end())
        return; // already loaded

    osg::Vec2f center(x+0.5f, y+0.5f);

    osg::ref_ptr<osg::Node> terrainNode = buildTerrain(NULL, 1.f, center);
    if (!terrainNode)
        return; // no terrain defined

    std::auto_ptr<GridElement> element (new GridElement);
    element->mNode = terrainNode;
    mTerrainRoot->addChild(element->mNode);

    // kdtree probably not needed with mNumSplits=4
    /*
    // build a kdtree to speed up intersection tests with the terrain
    // Note, the build could be optimized using a custom kdtree builder, since we know that the terrain can be represented by a quadtree
    geode->accept(*mKdTreeBuilder);
    */

    mGrid[std::make_pair(x,y)] = element.release();
}
コード例 #8
0
osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter)
{
    if (chunkSize * mNumSplits > 1.f)
    {
        // keep splitting
        osg::ref_ptr<osg::Group> group (new osg::Group);
        if (parent)
            parent->addChild(group);

        float newChunkSize = chunkSize/2.f;
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f));
        return group;
    }
    else
    {
        float minH, maxH;
        if (!mStorage->getMinMaxHeights(chunkSize, chunkCenter, minH, maxH))
            return NULL; // no terrain defined

        osg::Vec2f worldCenter = chunkCenter*mStorage->getCellWorldSize();
        osg::ref_ptr<SceneUtil::PositionAttitudeTransform> transform (new SceneUtil::PositionAttitudeTransform);
        transform->setPosition(osg::Vec3f(worldCenter.x(), worldCenter.y(), 0.f));

        if (parent)
            parent->addChild(transform);

        osg::ref_ptr<osg::Vec3Array> positions (new osg::Vec3Array);
        osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array);
        osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array);

        osg::ref_ptr<osg::VertexBufferObject> vbo (new osg::VertexBufferObject);
        positions->setVertexBufferObject(vbo);
        normals->setVertexBufferObject(vbo);
        colors->setVertexBufferObject(vbo);

        mStorage->fillVertexBuffers(0, chunkSize, chunkCenter, positions, normals, colors);

        osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
        geometry->setVertexArray(positions);
        geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX);
        geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
        geometry->setUseDisplayList(false);
        geometry->setUseVertexBufferObjects(true);

        geometry->addPrimitiveSet(mCache.getIndexBuffer(0));

        // we already know the bounding box, so no need to let OSG compute it.
        osg::Vec3f min(-0.5f*mStorage->getCellWorldSize()*chunkSize,
                       -0.5f*mStorage->getCellWorldSize()*chunkSize,
                       minH);
        osg::Vec3f max (0.5f*mStorage->getCellWorldSize()*chunkSize,
                           0.5f*mStorage->getCellWorldSize()*chunkSize,
                           maxH);
        osg::BoundingBox bounds(min, max);
        geometry->setComputeBoundingBoxCallback(new StaticBoundingBoxCallback(bounds));

        std::vector<LayerInfo> layerList;
        std::vector<osg::ref_ptr<osg::Image> > blendmaps;
        mStorage->getBlendmaps(chunkSize, chunkCenter, false, blendmaps, layerList);

        // For compiling textures, I don't think the osgFX::Effect does it correctly
        osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node);
        unsigned int dummyTextureCounter = 0;

        bool useShaders = mResourceSystem->getSceneManager()->getForceShaders();
        if (!mResourceSystem->getSceneManager()->getClampLighting())
            useShaders = true; // always use shaders when lighting is unclamped, this is to avoid lighting seams between a terrain chunk with normal maps and one without normal maps
        std::vector<TextureLayer> layers;
        {
            OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mTextureCacheMutex);
            for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it)
            {
                TextureLayer textureLayer;
                textureLayer.mSpecular = it->mSpecular;
                osg::ref_ptr<osg::Texture2D> texture = mTextureCache[it->mDiffuseMap];
                if (!texture)
                {
                    texture = new osg::Texture2D(mResourceSystem->getImageManager()->getImage(it->mDiffuseMap));
                    texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
                    texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
                    mResourceSystem->getSceneManager()->applyFilterSettings(texture);
                    mTextureCache[it->mDiffuseMap] = texture;
                }
                textureLayer.mDiffuseMap = texture;
                textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, texture);

                if (!it->mNormalMap.empty())
                {
                    texture = mTextureCache[it->mNormalMap];
                    if (!texture)
                    {
                        texture = new osg::Texture2D(mResourceSystem->getImageManager()->getImage(it->mNormalMap));
                        texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT);
                        texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT);
                        mResourceSystem->getSceneManager()->applyFilterSettings(texture);
                        mTextureCache[it->mNormalMap] = texture;
                    }
                    textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, texture);
                    textureLayer.mNormalMap = texture;
                }

                if (it->requiresShaders())
                    useShaders = true;

                layers.push_back(textureLayer);
            }
        }

        std::vector<osg::ref_ptr<osg::Texture2D> > blendmapTextures;
        for (std::vector<osg::ref_ptr<osg::Image> >::const_iterator it = blendmaps.begin(); it != blendmaps.end(); ++it)
        {
            osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D);
            texture->setImage(*it);
            texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
            texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
            texture->setResizeNonPowerOfTwoHint(false);
            blendmapTextures.push_back(texture);

            textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, blendmapTextures.back());
        }

        // use texture coordinates for both texture units, the layer texture and blend texture
        for (unsigned int i=0; i<2; ++i)
            geometry->setTexCoordArray(i, mCache.getUVBuffer());

        float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize;
        osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(mShaderManager ? useShaders : false, mResourceSystem->getSceneManager()->getForcePerPixelLighting(), mResourceSystem->getSceneManager()->getClampLighting(),
                                                                mShaderManager, layers, blendmapTextures, blendmapScale, blendmapScale));

        effect->addCullCallback(new SceneUtil::LightListCallback);

        transform->addChild(effect);

        osg::Node* toAttach = geometry.get();

        effect->addChild(toAttach);

        if (mIncrementalCompileOperation)
        {
            mIncrementalCompileOperation->add(toAttach);
            mIncrementalCompileOperation->add(textureCompileDummy);
        }

        return transform;
    }
}
コード例 #9
0
// Initialize GLUT & OpenSG and set up the rootNode
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    {
        // Set up Window
        WindowEventProducerRecPtr TutorialWindow = createNativeWindow();
        TutorialWindow->initWindow();

        // Create the SimpleSceneManager helper
        SimpleSceneManager sceneManager;
        TutorialWindow->setDisplayCallback(boost::bind(display, &sceneManager));
        TutorialWindow->setReshapeCallback(boost::bind(reshape, _1, &sceneManager));

        // Tell the Manager what to manage
        sceneManager.setWindow(TutorialWindow);

        //Attach to events
        TutorialWindow->connectMousePressed(boost::bind(mousePressed, _1, &sceneManager));
        TutorialWindow->connectMouseReleased(boost::bind(mouseReleased, _1, &sceneManager));
        TutorialWindow->connectMouseMoved(boost::bind(mouseMoved, _1, &sceneManager));
        TutorialWindow->connectMouseDragged(boost::bind(mouseDragged, _1, &sceneManager));
        TutorialWindow->connectMouseWheelMoved(boost::bind(mouseWheelMoved, _1, &sceneManager));
        TutorialWindow->connectKeyReleased(boost::bind(keyReleased, _1));

        //Make Main Scene Node
        NodeRefPtr scene = makeCoredNode<Group>();
        setName(scene, "scene");
        NodeRecPtr rootNode = Node::create();
        setName(rootNode, "rootNode");
        ComponentTransformRefPtr Trans = ComponentTransform::create();
        rootNode->setCore(Trans);
        rootNode->addChild(scene);

        //Light Beacon
        Matrix LightTransformMat;
        LightTransformMat.setTranslate(Vec3f(50.0,0.0,100.0));

        TransformRefPtr LightTransform = Transform::create();
        LightTransform->setMatrix(LightTransformMat);

        NodeRefPtr TutorialLightBeacon = Node::create();
        TutorialLightBeacon->setCore(LightTransform);

        //Light Node
        PointLightRefPtr TutorialLight = PointLight::create();
        TutorialLight->setBeacon(TutorialLightBeacon);

        NodeRefPtr TutorialLightNode = Node::create();
        TutorialLightNode->setCore(TutorialLight);

        scene->addChild(TutorialLightNode);
        scene->addChild(TutorialLightBeacon);


        //Setup Physics Scene
        PhysicsWorldRecPtr physicsWorld = PhysicsWorld::create();
        physicsWorld->setWorldContactSurfaceLayer(0.005);
        physicsWorld->setAutoDisableFlag(1);
        physicsWorld->setAutoDisableTime(0.75);
        physicsWorld->setWorldContactMaxCorrectingVel(100.0);
        physicsWorld->setGravity(Vec3f(0.0, 0.0, -9.81));

        PhysicsHashSpaceRecPtr physicsSpace = PhysicsHashSpace::create();

        //Setup the default collision parameters
        CollisionContactParametersRefPtr DefaultCollisionParams = CollisionContactParameters::createEmpty();
        DefaultCollisionParams->setMode(dContactApprox1);
        DefaultCollisionParams->setMu(1.0);
        DefaultCollisionParams->setMu2(0.0);
        DefaultCollisionParams->setBounce(0.0);
        DefaultCollisionParams->setBounceSpeedThreshold(0.0);
        DefaultCollisionParams->setSoftCFM(0.1);
        DefaultCollisionParams->setSoftERP(0.2);
        DefaultCollisionParams->setMotion1(0.0);
        DefaultCollisionParams->setMotion2(0.0);
        DefaultCollisionParams->setMotionN(0.0);
        DefaultCollisionParams->setSlip1(0.0);
        DefaultCollisionParams->setSlip2(0.0);

        physicsSpace->setDefaultCollisionParameters(DefaultCollisionParams);

        PhysicsHandlerRecPtr physHandler = PhysicsHandler::create();
        physHandler->setWorld(physicsWorld);
        physHandler->pushToSpaces(physicsSpace);
        physHandler->setUpdateNode(rootNode);
        physHandler->attachUpdateProducer(TutorialWindow);

        rootNode->addAttachment(physHandler);    
        rootNode->addAttachment(physicsWorld);
        rootNode->addAttachment(physicsSpace);


        /************************************************************************/
        /* create spaces, geoms and bodys                                                                     */
        /************************************************************************/
        //create a group for our space
        GroupRefPtr spaceGroup;
        NodeRecPtr spaceGroupNode = makeCoredNode<Group>(&spaceGroup);

        //create the ground terrain
        GeometryRefPtr TerrainGeo = buildTerrain(Vec2f(400.0,400.0),25,25);

        //and its Material
        SimpleMaterialRefPtr TerrainMat = SimpleMaterial::create();
        TerrainMat->setAmbient(Color3f(0.3,0.5,0.3));
        TerrainMat->setDiffuse(Color3f(0.5,0.9,0.5));
        TerrainGeo->setMaterial(TerrainMat);

        NodeRefPtr TerrainNode = Node::create();
        TerrainNode->setCore(TerrainGeo);


        //create ODE data
        PhysicsGeomRefPtr TerrainODEGeom = PhysicsTriMeshGeom::create();

        //add geom to space for collision
        TerrainODEGeom->setSpace(physicsSpace);
        //set the geometryNode to fill the ode-triMesh
        dynamic_pointer_cast<PhysicsTriMeshGeom>(TerrainODEGeom)->setGeometryNode(TerrainNode);

        //add attachments
        //add Attachments to nodes...
        spaceGroupNode->addAttachment(physicsSpace);
        spaceGroupNode->addChild(TerrainNode);

        TerrainNode->addAttachment(TerrainODEGeom);

        TutorialLightNode->addChild(spaceGroupNode);

        //Create Character
        PhysicsBodyRefPtr CharacterPhysicsBody = buildCharacter(Vec3f(5.0,5.0,10.0),
                                                                Pnt3f((Real32)(rand()%100)-50.0,(Real32)(rand()%100)-50.0,25.0),
                                                                spaceGroupNode,
                                                                physicsWorld,
                                                                physicsSpace);

        PhysicsLMotorJointRefPtr CharacterMover = buildMover(CharacterPhysicsBody);

        TutorialWindow->connectKeyPressed(boost::bind(keyPressed, _1,
                                                      spaceGroupNode.get(),
                                                      physicsWorld.get(),
                                                      physicsSpace.get()));

        TutorialWindow->connectUpdate(boost::bind(handleUpdate, _1,
                                                  CharacterPhysicsBody.get(),
                                                  CharacterMover.get()));

        // tell the manager what to manage
        sceneManager.setRoot  (rootNode);

        // show the whole rootNode
        sceneManager.showAll();

        Vec2f WinSize(TutorialWindow->getDesktopSize() * 0.85f);
        Pnt2f WinPos((TutorialWindow->getDesktopSize() - WinSize) *0.5);
        TutorialWindow->openWindow(WinPos,
                                   WinSize,
                                   "03CharacterTerrain");

        //Enter main Loop
        TutorialWindow->mainLoop();
    }

    osgExit();

    return 0;
}
コード例 #10
0
ファイル: main.cpp プロジェクト: mmcglynn45/NDFlightSim2.0
int main(int argc, char **argv) {
    buildTerrain();
    //Make the mian plane the lead friendly plane 
    friendlyPlanes.push_back(mainPlane);
    cDetector.carriers = &carriers;
    cDetector.tiles = &tiles;
    cDetector.friendlyPlanes = &friendlyPlanes;
    cDetector.enemyPlanes = &enemyPlanes;
    cDetector.mainPlane = &mainPlane;
    cDetector.explosives = &explosives;
    //buildEnemyPlanes();
    buildCarrierGroup();
    buildSilos();
    mainPlane.y = 45;
    mainPlane.explosives = &explosives;
    //explosives.generateExplosion(0, 45, -100, 0, 0, 0);

    glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowPosition(100,100);
	glutInitWindowSize(1024,768);
    //glutInitWindowSize(600,400);
	glutCreateWindow("Flight Simulator Basic");
    
	initScene();
    
    // Enable lighting
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHT1);
    GLfloat light_ambient[] = { 1, 1, 1, 1 };
    GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    GLfloat light_pos[] = { 0.0, 30.0, 0.0, 1 };
    GLfloat light_dir[] = { 0.0, 0, 0};
    GLfloat mat_specular[] = {0.3, 0.3, 0.3, 1.0};
    GLfloat mat_shininess[] = { 10.0 };
    glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_POSITION, light_pos);
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir);
    glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
    glClearColor(0.0f, 0.0f, .6f, .5f);
    
	glutIgnoreKeyRepeat(.05);
	glutSpecialFunc(pressKey);
    //glutKeyboardFunc(pressKey);
	glutSpecialUpFunc(releaseKey);
    
	glutDisplayFunc(renderScene);
	glutIdleFunc(renderScene);
    
	glutReshapeFunc(changeSize);
    
	glutMainLoop();
    
	return(0);
}
コード例 #11
0
ファイル: terraingrid.cpp プロジェクト: ChairGraveyard/TES3MP
osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chunkSize, const osg::Vec2f& chunkCenter)
{
    if (chunkSize * mNumSplits > 1.f)
    {
        // keep splitting
        osg::ref_ptr<osg::Group> group (new osg::Group);
        if (parent)
            parent->addChild(group);

        float newChunkSize = chunkSize/2.f;
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(newChunkSize/2.f, -newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, newChunkSize/2.f));
        buildTerrain(group, newChunkSize, chunkCenter + osg::Vec2f(-newChunkSize/2.f, -newChunkSize/2.f));
        return group;
    }
    else
    {
        float minH, maxH;
        if (!mStorage->getMinMaxHeights(chunkSize, chunkCenter, minH, maxH))
            return NULL; // no terrain defined

        osg::Vec2f worldCenter = chunkCenter*mStorage->getCellWorldSize();
        osg::ref_ptr<SceneUtil::PositionAttitudeTransform> transform (new SceneUtil::PositionAttitudeTransform);
        transform->setPosition(osg::Vec3f(worldCenter.x(), worldCenter.y(), 0.f));

        if (parent)
            parent->addChild(transform);

        osg::ref_ptr<osg::Vec3Array> positions (new osg::Vec3Array);
        osg::ref_ptr<osg::Vec3Array> normals (new osg::Vec3Array);
        osg::ref_ptr<osg::Vec4Array> colors (new osg::Vec4Array);

        osg::ref_ptr<osg::VertexBufferObject> vbo (new osg::VertexBufferObject);
        positions->setVertexBufferObject(vbo);
        normals->setVertexBufferObject(vbo);
        colors->setVertexBufferObject(vbo);

        mStorage->fillVertexBuffers(0, chunkSize, chunkCenter, positions, normals, colors);

        osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
        geometry->setVertexArray(positions);
        geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX);
        geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
        geometry->setUseDisplayList(false);
        geometry->setUseVertexBufferObjects(true);

        geometry->addPrimitiveSet(mCache.getIndexBuffer(0));

        // we already know the bounding box, so no need to let OSG compute it.
        osg::Vec3f min(-0.5f*mStorage->getCellWorldSize()*chunkSize,
                       -0.5f*mStorage->getCellWorldSize()*chunkSize,
                       minH);
        osg::Vec3f max (0.5f*mStorage->getCellWorldSize()*chunkSize,
                           0.5f*mStorage->getCellWorldSize()*chunkSize,
                           maxH);
        osg::BoundingBox bounds(min, max);
        geometry->setComputeBoundingBoxCallback(new StaticBoundingBoxCallback(bounds));

        std::vector<LayerInfo> layerList;
        std::vector<osg::ref_ptr<osg::Image> > blendmaps;
        mStorage->getBlendmaps(chunkSize, chunkCenter, false, blendmaps, layerList);

        // For compiling textures, I don't think the osgFX::Effect does it correctly
        osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node);

        std::vector<osg::ref_ptr<osg::Texture2D> > layerTextures;
        for (std::vector<LayerInfo>::const_iterator it = layerList.begin(); it != layerList.end(); ++it)
        {
            layerTextures.push_back(mResourceSystem->getTextureManager()->getTexture2D(it->mDiffuseMap, osg::Texture::REPEAT, osg::Texture::REPEAT));
            textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(0, layerTextures.back());
        }

        std::vector<osg::ref_ptr<osg::Texture2D> > blendmapTextures;
        for (std::vector<osg::ref_ptr<osg::Image> >::const_iterator it = blendmaps.begin(); it != blendmaps.end(); ++it)
        {
            osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D);
            texture->setImage(*it);
            texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
            texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
            texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR);
            texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
            texture->setResizeNonPowerOfTwoHint(false);
            blendmapTextures.push_back(texture);

            textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(0, layerTextures.back());
        }

        // use texture coordinates for both texture units, the layer texture and blend texture
        for (unsigned int i=0; i<2; ++i)
            geometry->setTexCoordArray(i, mCache.getUVBuffer());

        float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize;
        osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(layerTextures, blendmapTextures, blendmapScale, blendmapScale));

        effect->addCullCallback(new SceneUtil::LightListCallback);

        transform->addChild(effect);

#if OSG_VERSION_GREATER_OR_EQUAL(3,3,3)
        osg::Node* toAttach = geometry.get();
#else
        osg::ref_ptr<osg::Geode> geode (new osg::Geode);
        geode->addDrawable(geometry);
        osg::Node* toAttach = geode.get();
#endif

        effect->addChild(toAttach);

        if (mIncrementalCompileOperation)
        {
            mIncrementalCompileOperation->add(toAttach);
            mIncrementalCompileOperation->add(textureCompileDummy);
        }

        return transform;
    }
}
コード例 #12
0
ファイル: terraingrid.cpp プロジェクト: EmperorArthur/openmw
void TerrainGrid::cacheCell(View* view, int x, int y)
{
    osg::Vec2f center(x+0.5f, y+0.5f);
    static_cast<MyView*>(view)->mLoaded =  buildTerrain(NULL, 1.f, center);
}