#0 

05-04-2010 21:58:24

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Bonjours a tous !

Je traine depuis peut dans le forum officiel d'Irrlicht dans le but de trouver des codes a intégrer dans mon projet et j'ai trouvé ça : http://irrlicht.sourceforge.net/phpBB2/ … hp?t=10762
Le problème c'est que quand j'éssayait de l'intégrer dans mon projet, les herbes se méttait n'importe ou(a noter que quand j'utilise leurs démo ça marche) donc j'ai créé mon propre scenenode mais j'ai le même problème, les herbes ne se placent pas correctement que ce soit sur les axes x,y ou z .
voici mon code qui comprend la grosse class qui gère les herbes et en bas la petites fonction qui les assigne :
INFO - la définition des herbes se fait dans le constructeur, le reste a l'air de marcher correctement, mais si on suppose que le code du topic ne marchait pas dans mon projet mais corectement dans le sien, ça peut aussi venir de la déclaration .

Code c++ :


namespace irr
{
namespace scene
{

struct SGrassElement
{
    core::dimension2d<s32> sprite;
    video::S3DVertex points[4];
};
class IGrassSceneNode : public ISceneNode
{
public :
    IGrassSceneNode(ITerrainSceneNode* terrain, ISceneManager* mgr, s32 id, core::vector3d<s32> gridpos, char *filepath, video::IImage* heightMap, video::IImage* treeMap, video::IImage* grassMap, core::IWind *windgen);
    virtual ~IGrassSceneNode();

    virtual video::SMaterial& getMaterial(u32 i);
    virtual u32 getMaterialCount() const;
    virtual void OnRegisterSceneNode();
    virtual void OnAnimate(u32 timeMs);
    virtual void render();
    virtual const irr::core::aabbox3d<irr::f32>& getBoundingBox() const;

    void setImageCount(core::dimension2d<s32> ic);
    core::dimension2d<s32> getImageCount();
    void setDrawDistance(f32 draw);
    f32 getDrawDistance();
    void setMaxDensity(u32 max);
    u32 getMaxDensity();
    void setRefreshDelay(u32 ms);
    u32 getRefreshDelay();
    void setWindRes(u32 newres);
    u32 getWindRes();
private :
    video::IVideoDriver* m_driver;
    core::array<SGrassElement> grassElement;
    irr::u16 m_indices[6];
    u32 m_windRes;
    f32 m_drawDistance;
    core::dimension2d<s32> imagecount;
    core::dimension2d<f32> imagesize;
    core::IWind *m_windGen;
    s32 m_maxDensity;
    irr::video::SMaterial m_material;
    irr::core::aabbox3d<irr::f32> m_box;
    u32 m_timeMs;

    core::array<f32> v1;
    core::array<f32> v2;
    core::array<f32> v3;
    core::array<f32> v4;
};
IGrassSceneNode::IGrassSceneNode(ITerrainSceneNode* terrain, ISceneManager* mgr, s32 id, core::vector3d<s32> gridpos, char *filepath, video::IImage* heightMap, video::IImage* treeMap, video::IImage* grassMap, core::IWind *windgen) :
    ISceneNode((ITerrainSceneNode*)terrain, mgr, -1),
    m_drawDistance(2),
    m_maxDensity(800),
    m_box(terrain->getBoundingBox()),
    m_windGen(windgen)
{
    m_driver = SceneManager->getVideoDriver();
    m_material.Wireframe = false;
    m_material.Lighting = false;
    m_material.BackfaceCulling = false;
    m_indices[0] = 3;
    m_indices[1] = 2;
    m_indices[2] = 0;
    m_indices[3] = 0;
    m_indices[4] = 2;
    m_indices[5] = 1;
    //setPosition(core::vector3df((f32)(gridpos.X*(terrain->getBoundingBox().MaxEdge - terrain->getBoundingBox().MinEdge).X),0 , (f32)(gridpos.Z*(terrain->getBoundingBox().MaxEdge - terrain->getBoundingBox().MinEdge).Z)));
    setPosition(terrain->getPosition());
    setWindRes(5);
    setImageCount(core::dimension2d<s32>(4,2));
    u32 m_timeMs = 0;
    core::matrix4 m;
    m.setRotationDegrees(terrain->getRotation());
    m.setTranslation(terrain->getAbsolutePosition());
    //------------------------------------------------------GRASS------------------------------------------------------
    s32 count = 15000/*((terrain->getBoundingBox().MaxEdge - terrain->getBoundingBox().MinEdge).X * (terrain->getBoundingBox().MaxEdge - terrain->getBoundingBox().MinEdge).Z) / 100*/;
    grassElement.set_used(count);
    for(s32 i = 0; i < count; i++)
    {
    //initialisation
        //texture
        grassElement[i].sprite.Width  = rand() % imagecount.Width;
        if (i<30)
            grassElement[i].sprite.Height = 1 *(rand() % imagecount.Height);
        else
            grassElement[i].sprite.Height = 0;
        //position
        f32 x = (rand() % (u32)(terrain->getTransformedBoundingBox().MaxEdge - terrain->getTransformedBoundingBox().MinEdge).X / 2);
        f32 z = (rand() % (u32)(terrain->getTransformedBoundingBox().MaxEdge - terrain->getTransformedBoundingBox().MinEdge).Z / 2);

        /*x -=  (terrain->getBoundingBox().MaxEdge - terrain->getBoundingBox().MinEdge).X / 2;
        z -=  (terrain->getBoundingBox().MaxEdge - terrain->getBoundingBox().MinEdge).Z / 2;*/

        f32 y = terrain->getHeight(x, z);
        //rotation
        f32 rotation = (rand() % 3600) / 10.0f;
    //verification
        irr::core::vector3df posElement(x, y, z);
        m.transformVect(posElement);
        core::vector3df p = getPosition() + posElement - terrain->getPosition();
        core::vector3df xz(p.X/terrain->getScale().X,0.0f,p.Z/terrain->getScale().Z);   
        s32 x1 = (s32)floorf(xz.X);
        s32 z1 = (s32)floorf(xz.Z);
        //destruction si les herbes sont en dehors du terrain
        if(terrain->getTransformedBoundingBox().isPointInside(p))
        {
            --count; --i;
            grassElement.set_used(count);
            continue;
        }
        //destruction si les herbes sont trop petites
        video::SColor cDensity  = grassMap->getPixel(x1,z1);
        core::dimension2d<f32> size((f32)(rand() % 2 + 2), (f32)cDensity.getBlue()/5.0f);
        if ((u32)(rand() % 255) > cDensity.getAlpha() || cDensity.getAlpha() < 1 )
        {
            --count; --i;
            grassElement.set_used(count);
            continue; 
        }
    //definition
        //calcul de la position des points
        core::vector3df points[4];
        points[0] = core::vector3df(x, y, z);
        points[1] = core::vector3df(x + size.Width, y, z);
        points[2] = core::vector3df(x + size.Width, y + size.Height, z);
        points[3] = core::vector3df(x, y + size.Height, z);
        //calcul de la rotation des points
        s32 distance = sqrt(pow(size.Width, 2) + pow(size.Height, 2));
        irr::core::vector3df rotToPos[2];
        rotToPos[0].X = distance * cos(rotation);
        rotToPos[0].Z = distance * sin(rotation);
        rotToPos[0].Y = 0;
        rotToPos[1].X = distance * cos(rotation + 180);
        rotToPos[1].Z = distance * sin(rotation + 180);
        rotToPos[1].Y = 0;
        points[0] += rotToPos[0];
        points[1] += rotToPos[0];
        points[2] += rotToPos[0];
        points[3] += rotToPos[0];
        s32 indiceTxt1 = i % (imagecount.Width - 1);
        s32 indiceTxt2 = i % (imagecount.Height - 1);
        s32 arrpos = (imagecount.Width * grassElement[i].sprite.Height) + grassElement[i].sprite.Width;
        grassElement[i].points[0] = video::S3DVertex(points[0].X, points[0].Y, points[0].Z, 0, 0, 0,  irr::video::SColor(255,0,255,255), v1[arrpos], v2[arrpos]);
        grassElement[i].points[1] = video::S3DVertex(points[1].X, points[1].Y, points[1].Z, 0, 0, 0,  irr::video::SColor(255,0,255,255), v4[arrpos], v2[arrpos]);
        grassElement[i].points[2] = video::S3DVertex(points[2].X, points[2].Y, points[2].Z, 0, 0, 0,  irr::video::SColor(255,0,255,255), v4[arrpos], v3[arrpos]);
        grassElement[i].points[3] = video::S3DVertex(points[3].X, points[3].Y, points[3].Z, 0, 0, 0,  irr::video::SColor(255,0,255,255), v1[arrpos], v3[arrpos]);
    }
    //------------------------------------------------------TREE-------------------------------------------------------
              //on verra ça après, il a suffisamment de problème avec les herbes
}
IGrassSceneNode::~IGrassSceneNode()
{
}
video::SMaterial& IGrassSceneNode::getMaterial(u32 i)
{
    return m_material;
}
u32 IGrassSceneNode::getMaterialCount() const
{
    return 1;
}
void IGrassSceneNode::OnRegisterSceneNode()
{
    if(IsVisible)
        SceneManager->registerNodeForRendering(this, irr::scene::ESNRP_SOLID);

    ISceneNode::OnRegisterSceneNode();
}
void IGrassSceneNode::OnAnimate(u32 timeMs)
{
    m_timeMs = timeMs;
    ISceneNode::OnAnimate(timeMs);
}
void IGrassSceneNode::render()
{
    m_driver->setMaterial(m_material);
    m_driver->setTransform(irr::video::ETS_WORLD, AbsoluteTransformation);
    irr::scene::ICameraSceneNode *camera = SceneManager->getActiveCamera();
    for(u32 i = 0; i < grassElement.size(); i += (m_maxDensity) / 10)
    {
        std::cout<<i<<std::endl;
        if((grassElement[i].points[0].Pos - camera->getPosition()).X < m_drawDistance && (grassElement[i].points[0].Pos - camera->getPosition()).Z < m_drawDistance)
        {
            std::cout<<i<<std::endl;
            core::vector2df add = m_windGen->getWind(core::vector3df(0, 0, 0), m_timeMs);
            add *= 0.75;
            grassElement[i].points[2].Pos.Z += add.X;
            grassElement[i].points[2].Pos.Y += add.Y;
            grassElement[i].points[3].Pos.Z += add.X;
            grassElement[i].points[3].Pos.Y += add.Y;
            m_driver->drawIndexedTriangleList(&grassElement[i].points[0], 4, m_indices, 2);
            grassElement[i].points[2].Pos.Z -= add.X;
            grassElement[i].points[2].Pos.Y -= add.Y;
            grassElement[i].points[3].Pos.Z -= add.X;
            grassElement[i].points[3].Pos.Y -= add.Y;
        }
    }
}
void IGrassSceneNode::setWindRes(u32 newres)
{
    m_windRes = newres;
}
u32 IGrassSceneNode::getWindRes()
{
    return m_windRes;
}
core::dimension2d<s32> IGrassSceneNode::getImageCount()
{
    return imagecount;
}
void IGrassSceneNode::setImageCount(core::dimension2d<s32> ic)
{
    imagecount = ic;
    imagesize.Width= 1.0f / f32(imagecount.Width);
    imagesize.Height=1.0f / f32(imagecount.Height);

    v1.set_used(imagecount.Width * imagecount.Height);
    v2.set_used(imagecount.Width * imagecount.Height);
    v3.set_used(imagecount.Width * imagecount.Height);
    v4.set_used(imagecount.Width * imagecount.Height);

    for (int x=0;x<imagecount.Width; ++x)
        for (int y=0;y<imagecount.Height; ++y)
        {
            v1[ (imagecount.Width*y)+x ] = imagesize.Width  *  x;
            v2[ (imagecount.Width*y)+x ] = imagesize.Height * (y+1);
            v3[ (imagecount.Width*y)+x ] = imagesize.Height *  y;
            v4[ (imagecount.Width*y)+x ] = imagesize.Width  * (x+1);
        }
}
void IGrassSceneNode::setDrawDistance(f32 draw)
{
    m_drawDistance = draw*draw;
}
f32 IGrassSceneNode::getDrawDistance()
{
    return (f32)sqrt(m_drawDistance);
}
void IGrassSceneNode::setMaxDensity(u32 max)
{
    m_maxDensity = max;
}
u32 IGrassSceneNode::getMaxDensity()
{
    return m_maxDensity;
}
const irr::core::aabbox3d<irr::f32>& IGrassSceneNode::getBoundingBox() const
{
    return m_box;
}


} // end namespace scene
} // end namespace irr

namespace map
{
    Grass::Grass(GameEngine* scene, irr::scene::ITerrainSceneNode* terrain)
    {
        heightMap = scene->getDevice()->getVideoDriver()->createImageFromFile("heightmap.bmp");
        textureMap = scene->getDevice()->getVideoDriver()->createImageFromFile("treemap.bmp");
        grassMap = scene->getDevice()->getVideoDriver()->createImageFromFile("grassmap.png");
        irr::video::ITexture* texture = scene->getDevice()->getVideoDriver()->getTexture("grass.png");
        int height = 10;
        int width = 10;
        for (int x = 0; x < width; x++)
        {
            for (int z = 0; z < height; z++)
            {
                m_listeGrassNode.push_back(new irr::scene::IGrassSceneNode(terrain, scene->getDevice()->getSceneManager(), -1, irr::core::vector3d<irr::s32>(x,0,z), "grass", heightMap, textureMap, grassMap, scene->getWind()));
                m_listeGrassNode[x*width + z]->setMaterialFlag(irr::video::EMF_LIGHTING, false);
                m_listeGrassNode[x*width + z]->setMaterialType(irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL);       
                m_listeGrassNode[x*width + z]->setMaterialTexture(0, texture);
                m_listeGrassNode[x*width + z]->drop();
            }
        }
    }
}

Dernière modification par Ilovechocolat (05-04-2010 22:00:02)

Hors ligne


#1 

06-04-2010 22:07:31

nabouill
Abonné
Date d'inscription: 17-09-2009
Messages: 242
Corrections: 1

je pense avoir une petite idée, (mais je préférais attendre de voir si quelqu'un en avait une avant de dire la mienne car je vais peut-être dire un connerie)
en 1_ je pensais a tes fichiers heightmap et/ou grassmap.
et 2_ la taille de ton terrain, est-il en taille de 1,1,1 ? car j'ai l'impression (enfin en tout cas dans le code de l'autre, que le calcule de la position de l'herbe se fait avec la taille du terrain, qui dans sont exemple est de 1 sur tout les axes.

en espérant que ça puisse t'aider, bon courage.


mes sites: www.manga-vf.fr et www.series-vf.fr

Hors ligne


#2 

07-04-2010 13:36:26

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Mon terrain est en position et rotation 0 mais en scale ça donne : 10 / 1 / 10
voila la déclaration de ma heightmap :

Code c++ :

        irr::scene::ITerrainSceneNode* nodeTerrain = m_sceneManager->addTerrainSceneNode("heightmap.bmp", 0, -1, irr::core::vector3df(0, 0, 0), irr::core::vector3df(0, 0, 0), irr::core::vector3df(10, 1, 10)/*(40, 4.0f, 40)*/, irr::video::SColor ( 255, 255, 255, 255 ), 5, irr::scene::ETPS_17, 4);
        m_room = (irr::scene::IAnimatedMesh*)nodeTerrain->getMesh();
        m_Nroom = (irr::scene::ISceneNode*)nodeTerrain;
        selector = m_sceneManager->createTerrainTriangleSelector(nodeTerrain);
        m_Nroom->setMaterialTexture(0, m_driver->getTexture("treemap.bmp"));
        m_Nroom->setMaterialTexture(1, m_driver->getTexture("grassmap.png"));
        nodeTerrain->scaleTexture(1.0f, 10.0f);
        m_Nroom->setMaterialType(irr::video::EMT_DETAIL_MAP);
        map::Grass grassManager(this, nodeTerrain);

Dernière modification par Ilovechocolat (07-04-2010 14:59:53)

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
881 membres
1426 sujets
11116 messages
Dernier membre inscrit: Bidule
17 invités en ligne
Aucun membre connecté
RSS Feed