Posted: Thu Mar 05, 2009 1:08 pm
lol, nice cow
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
thanks for the comment, the game is done yet still alot of work to do.grayman wrote:Amazing & Beautifull, nice job!!! May we see the code? its OpenSource? Where can i play it? I love harvest moon and your game its a huge oportunity to make my own version? what you think? i could help you with the models...let me join? i use blender and .b3d too.
Code: Select all
#ifndef ____KORS_GRASS_NODE____
#define ____KORS_GRASS_NODE____
#include <irrlicht.h>
namespace irr
{
namespace scene
{
struct SGrassContainer{
public:
core::vector3df patchPosition; // posisi relative patch // patch's relative position
core::vector3df windVector;
core::vector3df patchPoint[8]; // 2 rumput per patch // 2 grasses per patch
f32 grassHeight; // tinggi rumput // grash height
core::vector3df preasureApply; // tekanan diatas rumput // preasure above grass
};
class CTerrainGrassNode: public ISceneNode{
public:
//! constructor
CTerrainGrassNode(
ISceneNode* parent,
ISceneManager* mgr,
s32 id,
video::IImage* heighMap,
video::IImage* grassMap);
// destructor //destructor
virtual ~CTerrainGrassNode();
// Returns the material based on the zero based index i.
virtual video::SMaterial& getMaterial(u32 num);
// Returns amount of materials used by this scene node.
virtual u32 getMaterialCount();
// pre render
virtual void OnRegisterSceneNode();
// animate the grass
virtual void OnAnimate(u32 timeMs);
//render
virtual void render();
virtual const core::aabbox3d<f32>& getBoundingBox() const;
void applyPreasureOn3DPosition(core::vector3df position, core::vector3df preasure);
private:
video::IImage* heightMap; // peta kontur // height map
video::IImage* grassMap; // peta persebaran rumput // grass distribution
core::aabbox3d<f32> Box; // bounding box // bounding box
core::array<SGrassContainer> grasses; // isi rumput-rumput // grass container
video::SMaterial Material; // material rumput // grass material
core::array<video::S3DVertex> Vertices; // 8 vertex tiap patch // 8 vertices per patch
core::array<u16> Indices; // 24 index tiap pactch // 24 index per patch
f32 patchSize;
f32 preasureDecFac;
f32 windCompletion;
f32 drawDistance;
u32 updateDelay;
u32 lastUpdate;
bool relocatePrimitive;
bool initGrass();
void allocatePrimitives();
bool allocated;
};
}// end of namespace scene
}// end of namespace irr
#endif
Code: Select all
#include <irrlicht.h>
#include "CTerrainGrassNode.h"
namespace irr
{
namespace scene
{
//! constructor
CTerrainGrassNode::CTerrainGrassNode(
ISceneNode* parent,
ISceneManager* mgr,
s32 id,
video::IImage* heighMap,
video::IImage* grassMap):scene::ISceneNode(parent,mgr,id){
this->SceneManager= mgr;
this->Parent = parent;
this->grassMap = grassMap;
this->heightMap = heighMap;
this->preasureDecFac = 0.5;
this->windCompletion = 0.0;
this->updateDelay = 100;
this->lastUpdate = 0;
this->relocatePrimitive = true;
this->drawDistance = 10000;
initGrass();
patchSize = 1;
//Material.Lighting = false;
Material.BackfaceCulling = false;
Material.ZWriteEnable = true;
//Material.FogEnable = true;
Material.ZBuffer = 1;
//setAutomaticCulling(EAC_BOX );
Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
//Material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
//Material.MaterialTypeParam = 1;
Material.TextureLayer[0].Texture = SceneManager->getVideoDriver()->getTexture("resh/tilingSys/grass.png");
//Material.TextureLayer[0].Texture = SceneManager->getVideoDriver()->getTexture("resh/tilingSys/rumput.png");
}
//! destructor
CTerrainGrassNode::~CTerrainGrassNode(){
}
// Returns the material based on the zero based index i.
video::SMaterial& CTerrainGrassNode::getMaterial(u32 num){
return Material;
}
//Returns amount of materials used by this scene node.
u32 CTerrainGrassNode::getMaterialCount(){
return 1;
}
//pre render
void CTerrainGrassNode::OnRegisterSceneNode(){
if (IsVisible)
SceneManager->registerNodeForRendering(this,ESNRP_TRANSPARENT );
ISceneNode::OnRegisterSceneNode();
}
//nimate the grass
void CTerrainGrassNode::OnAnimate(u32 timeMs){
if(lastUpdate == 0){
lastUpdate = timeMs;
}
if(timeMs>=lastUpdate+updateDelay){
f32 i = 0;
f32 j = 0;
if(windCompletion<2.0){
windCompletion+=0.05;
}else{
windCompletion = 0;
}
for(i=0;i<(f32)grassMap->getDimension().Height;i++){
for(j=0;j<(f32)grassMap->getDimension().Width;j++){
u32 index = ((u32)i * grassMap->getDimension().Height + (u32)j);
if(windCompletion==0.0){
srand(index*timeMs);
grasses[index].windVector = core::vector3df(0.5-((rand()%1000)/100),
0,
0.5-((rand()%1000)/100))/8;
}else{
grasses[index].grassHeight = (f32)(grassMap->getPixel((u32)i,(u32)j).getGreen())/255*5;
if(grasses[index].grassHeight>0){
f32 interpolator = windCompletion-1;
if(interpolator<0){
interpolator*=-1;
}
grasses[index].patchPoint[2] = grasses[index].patchPoint[1].getInterpolated(grasses[index].patchPoint[1]+grasses[index].windVector,interpolator)+core::vector3df(0,grasses[index].grassHeight,0)+grasses[index].preasureApply;
grasses[index].patchPoint[3] = grasses[index].patchPoint[0].getInterpolated(grasses[index].patchPoint[0]+grasses[index].windVector,interpolator)+core::vector3df(0,grasses[index].grassHeight,0)+grasses[index].preasureApply;
grasses[index].patchPoint[6] = grasses[index].patchPoint[5].getInterpolated(grasses[index].patchPoint[5]+grasses[index].windVector,interpolator)+core::vector3df(0,grasses[index].grassHeight,0)+grasses[index].preasureApply;
grasses[index].patchPoint[7] = grasses[index].patchPoint[4].getInterpolated(grasses[index].patchPoint[4]+grasses[index].windVector,interpolator)+core::vector3df(0,grasses[index].grassHeight,0)+grasses[index].preasureApply;
grasses[index].preasureApply /= 1.1 ;//grasses[index].preasureApply.getInterpolated(core::vector3df(0,0,0),0.005);
}
}
}
}
if(windCompletion==0.0){
windCompletion = 0.1;
}
relocatePrimitive = true;
lastUpdate = timeMs;
}
ISceneNode::OnAnimate(timeMs);
}
//render
void CTerrainGrassNode::render(){
if(relocatePrimitive){
allocatePrimitives();
relocatePrimitive = false;
}
if((Vertices.size()>0)&&(Indices.size()>0)){
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(Material);
driver->drawIndexedTriangleList(Vertices.pointer(),
Vertices.size(),
Indices.pointer(),
Indices.size()/3);
}
}
const core::aabbox3d<f32>& CTerrainGrassNode::getBoundingBox() const{
return Box;
}
bool CTerrainGrassNode::initGrass(){
if(!heightMap||!grassMap){
return false;
}else{
//printf("init grass\n");
f32 i = 0;
f32 j = 0;
f32 scaling = (f32)heightMap->getDimension().Height/(f32)grassMap->getDimension().Height;
for(i=0;i<(f32)grassMap->getDimension().Height;i++){
for(j=0;j<(f32)grassMap->getDimension().Width;j++){
//printf("[%f,%f]\n",i,j);
//randoming translation
//core::vector3df randTrans = core::vector3df(0.5-(rand()%1000/100),
// 0,
// 0.5-(rand()%1000/100))/2;
//randoming rotation
f32 randRotation = ((rand()%100));
//printf("%f\n",randRotation);
//creating pre primitive
f32 x = ((f32)grassMap->getDimension().Height-i-1)*scaling;//* patchSize;
f32 z = j*scaling;//* patchSize;
SGrassContainer grass;
f32 height = (f32)(heightMap->getPixel((u32)((i+6)*scaling),(u32)((j+1)*scaling)).getGreen());
grass.patchPosition = core::vector3df(x,height,z);//+randTrans;
grass.grassHeight = (f32)(grassMap->getPixel((u32)i,(u32)j).getGreen())/255*5;
grass.preasureApply = core::vector3df(0,0,0);;
grass.windVector = core::vector3df(0.5-(rand()%1000/100),
0,
0.5-(rand()%1000/100))/2;
grass.patchPoint[0] = grass.patchPosition + core::vector3df(1,0,1);
grass.patchPoint[1] = grass.patchPosition + core::vector3df(-1,0,-1);
grass.patchPoint[2] = grass.patchPosition + core::vector3df(-1,grass.grassHeight,-1);
grass.patchPoint[3] = grass.patchPosition + core::vector3df(1,grass.grassHeight,1);
grass.patchPoint[4] = grass.patchPosition + core::vector3df(1,0,-1);
grass.patchPoint[5] = grass.patchPosition + core::vector3df(-1,0,1);
grass.patchPoint[6] = grass.patchPosition + core::vector3df(-1,grass.grassHeight,1);
grass.patchPoint[7] = grass.patchPosition + core::vector3df(1,grass.grassHeight,-1);
for(u16 k = 0; k<8;k++){
grass.patchPoint[k].rotateXZBy(randRotation, grass.patchPosition);
}
grasses.push_back(grass);
//}*/
}
}
return true;
}
}
void CTerrainGrassNode::applyPreasureOn3DPosition(core::vector3df position,core::vector3df preasure){
//f32 scaling = (f32)heightMap->getDimension().Height/(f32)grassMap->getDimension().Height;
f32 xPos = 255-position.X;//scaling;
f32 yPos = position.Z;//scaling;
//printf("[%f,%f]\n",xPos,yPos);
u32 index = ((u32)xPos * grassMap->getDimension().Height + (u32)yPos);
grasses[index].preasureApply = preasure;
}
void CTerrainGrassNode::allocatePrimitives(){
ICameraSceneNode* cam = 0;
cam = SceneManager->getActiveCamera();
if(!cam){
return;
}else{
core::aabbox3d<f32> clippingBox = cam->getViewFrustum()->boundingBox;
core::vector3df cameraPos = cam->getPosition();
s32 size = grassMap->getDimension().Width;
Vertices.clear();
Indices.clear();
u32 index;
u32 indiceCount = 0;
//printf("updating primitive\n");
Box.reset(getPosition());
for(index=0;index<grasses.size();index++)
//printf("testing index %d/%d\n", index,grasses.size());
if((index>=0)&&
(index<grasses.size()))
if((clippingBox.isPointInside(grasses[index].patchPosition*25))&&
(cameraPos.getDistanceFrom(grasses[index].patchPosition*25)<=drawDistance)){
if(grasses[index].grassHeight>0){
Box.addInternalPoint(grasses[index].patchPosition);
for(u32 i = 0 ; i< 8 ; i++){
Box.addInternalPoint(grasses[index].patchPoint[i]);
core::vector2df tCoord = core::vector2df(0,1);
if((i == 1)||
(i == 2)||
(i == 5)||
(i == 6)){
tCoord.X = 2.0;
}
if((i == 2)||
(i == 3)||
(i == 6)||
(i == 7)){
tCoord.Y = 0.1;
}
Vertices.push_back(video::S3DVertex(grasses[index].patchPoint[i],
core::vector3df (0,1,0),
video::SColor (255,255,255,255),
tCoord));
}
Indices.push_back(indiceCount); //printf("%d\n",indiceCount);
Indices.push_back(indiceCount+1);//printf("%d\n",indiceCount+1);
Indices.push_back(indiceCount+2);//printf("%d\n",indiceCount+2);
Indices.push_back(indiceCount+2);//printf("%d\n",indiceCount+2);
Indices.push_back(indiceCount+3);//printf("%d\n",indiceCount+3);
Indices.push_back(indiceCount); //printf("%d\n",indiceCount);
Indices.push_back(indiceCount+4);//printf("%d\n",indiceCount+4);
Indices.push_back(indiceCount+5);//printf("%d\n",indiceCount+5);
Indices.push_back(indiceCount+6);//printf("%d\n",indiceCount+6);
Indices.push_back(indiceCount+6);//printf("%d\n",indiceCount+6);
Indices.push_back(indiceCount+7);//printf("%d\n",indiceCount+7);
Indices.push_back(indiceCount+4);//printf("%d\n",indiceCount+4);
indiceCount+=8;
}
//printf("add 2 quads\n");
}
}
}
}// end of namespace scene
}// end of namespace irr
nice work. keep it up, and thanks for the comment. i'll contact you if i need u.Systemerror wrote:This looks really good, keep it up and don't give up, I aim to get my game "Deep Sleep" selling one day, maybe even in shops Razz it's hard and you always come across obstacles but don't gice up!
i've use the const qualifier, and now it works.hybrid wrote:You didn't use the proper function qualifiers, getMaterialCount needs to be const.
Try to use the ALPHA_REF material for leafs and grass.
yes now all allright.hybrid wrote:Check the material types. There's EMT_TRANSPARENT_ALPHA_CHANNEL and EMT_TRANSPARENT_ALPHA_CHANNEL_REF. The latter is really good for intersecting transparency layers with only a very thing border which is not fully opaque or fully transparent.