[help] Problem deforming terrain using PLSM2

jguerra

14-09-2007 17:24:05

Hi.
I've started "messing" with Ogre3D and PLSM2 only a week ago, and I'm trying to create a terrain deformation tool. After struggling to make the terrain deform, i get this problem....











I'm using the terrain sample Alpes with all the default configurations, except this one that i've placed in Alpes.cfg:

Deformable=yes


This is the code i'm using to deform the terrain:

void deform ()
{
float mBrushStrength = 0.05f;
int value = 50;

mSceneMgr->setOption("BrushScale", &mBrushStrength);
mSceneMgr->setOption("BrushSize", &mBrushSize);
Ray pickRay = mCamera->getCameraToViewportRay(mMouseCursor->getX(),mMouseCursor->getY());

RaySceneQuery* mRayQuery;
mRayQuery = mSceneMgr->createRayQuery(Ray(Vector3::ZERO, Vector3::NEGATIVE_UNIT_Y));

mRayQuery->setRay (pickRay);

mRayQuery->setQueryTypeMask(Ogre::SceneManager::WORLD_GEOMETRY_TYPE_MASK);
mRayQuery->setWorldFragmentType(SceneQuery::WFT_SINGLE_INTERSECTION);
mRayQuery->execute ();

RaySceneQueryResult& qryResult = mRayQuery->execute();
RaySceneQueryResult::iterator it = qryResult.begin();

if (it != qryResult.end() && it->worldFragment)
{
mSceneMgr->setOption( "DeformationCenter",&(it->worldFragment->singleIntersection));

}
}


I have no idea on how to solve this problem.... so.... any help is welcome.
Thanks.

jguerra

17-09-2007 12:04:00

Giving it another go, i used the option "setHeightCenter" to raise a plain terrain. It worked!!
So, i tried to use the same option to create a rounded surface to see if the problem remained.

And... it did...

This is the code i used:

Ogre::Vector3 Center;
Ogre::uint i;

i = 180;
mSceneMgr->setOption("BrushArrayWidth", &i);
mSceneMgr->setOption("BrushArrayHeight", &i);

Ogre::Real * deltaArray = new Ogre::Real[i * i];
mSceneMgr->setOption("BrushArray", deltaArray);
mSceneMgr->setOption("fillBrushArray", &Center);

for (int j = 0 ; j < i*i ; j++)
deltaArray[j] = -50*sin(DEG2RAD((j/180)%180));

mSceneMgr->setOption("setHeightCenter", &Center);



And the result:


Don't know if it helps, but I'm using Linux with a Nvidia video card with the drivers up to date.

I'm stuck in this problem.... any help is appreciated.
Thanks.

jguerra

18-09-2007 16:57:56

Another update on the problem....

Now I'm saving the deformations on the terrain and when i restart the application everything is fine..... :shock:

What kind of problem is this? normals?

jguerra

24-09-2007 17:13:52

Well.. i still have no solution for my problem... Any answers out there?

I getting somewhat desperate and already looking for alternatives, does anyone know other solutions as good as plsm2 for big terrains with real time deformation? Or.... when plsm3 is excepted?

Xavyiy

24-09-2007 18:29:02


Ogre::Vector3 Center = Ogre::Vector3(0,0,0);
Ogre::uint i;

i = 180;
mSceneMgr->setOption("BrushArrayWidth", &i);
mSceneMgr->setOption("BrushArrayHeight", &i);

Ogre::Real * deltaArray = new Ogre::Real[i * i];

for (int j = 0 ; j < i*i ; j++)
deltaArray[j] = -50*sin(DEG2RAD((j/180)%180));

mSceneMgr->setOption("BrushArray", deltaArray);

Ogre::Real BScale = 0.1;

mSceneMgr->setOption("BrushScale", &BScale);
mSceneMgr->setOption("DeformationCenter", &Center);


mSceneMgr->setOption("BrushArray", deltaArray); need to be called after asign valors to the real array, and for deform terrain I use "DeformationCenter", try it, and sorry for my little English.

jguerra

25-09-2007 14:07:54

Thanks for the reply, but it didn't work.... Same weird results. :(

Xavyiy

25-09-2007 16:05:12

Try to change:

for (int j = 0 ; j < i*i ; j++)
deltaArray[j] = -50*sin(DEG2RAD((j/180)%180));


to

for (int j = 0 ; j < i*i ; j++)
deltaArray[j] = 5;


and told us if you get the same errors.

jguerra

25-09-2007 17:23:51

Did try that, didn't work.

From a simple PageUpdate i get the following result....






Ogre::uint x1 = 0;
mScnMgr->getOption("CurrentCameraPageX", &x1);
Ogre::uint z1 = 0;
mScnMgr->getOption("CurrentCameraPageZ", &z1);

mScnMgr->setOption("PageUpdate", &Vector2(x1,z1));


I've even changed the .gen.cfg to work in a "one-page" terrain, hoping that a would get a result that would be more debugable. But the only conclusion i was able to achieve was that that "stretch" effect is created by pulling some vertex (?) to the tile 0,0 of the page where the deformation took place.
I don't know if this is the right conclusion, but i think it has something to do with this.

danto

18-11-2007 17:21:37

I'm experiencing the same issue as above and have noticed other threads with a similar issue. I've been searching around the forums and have yet to find a resolution. Was this problem resolve and if so how?

Thanks.

bibiteinfo

18-11-2007 20:36:21

For my part, the deform circle was not set correctly, there was a problem with the brush initialization. It solved the issue ...

danto

18-11-2007 21:03:50

Could you give an example of the initialization for the brush?

bibiteinfo

18-11-2007 21:20:06


//------------------------------------------------------------------------------------------------
void PagingLandscapeEditorPlugin::updateBrushArray(int size)
{
delete[] mBrushArray;

Image image;
std::stringstream brushName;
brushName << size << "x" << size << "CircularBrush.bmp";
image.load(brushName.str(), "General");
const uint bpp = static_cast<uint>(PixelUtil::getNumElemBytes(image.getFormat()));

if(image.getWidth() != image.getHeight() || bpp != 1)
{
//do nothing
OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid brush image.", "PagingLandscapeEditorPlugin");
}
else
{
float scale = 1.0f / 65535.0f;

float height = 0.0f;
const uchar* const ogre_restrict imageData = image.getData();
size_t dataSize = image.getSize();
mBrushArray = new float[image.getWidth() * image.getHeight()];
//float* tempData = new float[image.getWidth() * image.getHeight()];
uint j = 0;

float maxHeight = 0.0f;

for(uint srcPos = 0; srcPos < image.getWidth() * image.getHeight() * bpp; srcPos += bpp)
{

#if OGRE_ENDIAN == ENDIAN_BIG
ushort val = imageData[srcPos] << 8;
val += imageData[srcPos];
#else
ushort val = imageData[srcPos];
val += imageData[srcPos] << 8;
#endif
height = ((float)(val)) * scale;
mBrushArray[j++] = height;
}

const uint brushArrayWidth = static_cast<uint>(image.getWidth());
const uint brushArrayHeight = static_cast<uint>(image.getHeight());
mBrushArrayWidth = brushArrayWidth;
mSceneMgr->setOption("BrushArrayHeight", &brushArrayHeight);
mSceneMgr->setOption("BrushArrayWidth", &brushArrayWidth);
mSceneMgr->setOption("BrushArray", mBrushArray);

}
}


The interesting part is this one


for(uint srcPos = 0; srcPos < image.getWidth() * image.getHeight() * bpp; srcPos += bpp)
{
#if OGRE_ENDIAN == ENDIAN_BIG
ushort val = imageData[srcPos] << 8;
val += imageData[srcPos];
#else
ushort val = imageData[srcPos];
val += imageData[srcPos] << 8;
#endif
height = ((float)(val)) * scale;
mBrushArray[j++] = height;
}

danto

18-11-2007 21:49:13

Thank you for the information. I looked over what you have as well as what I have and it's still not working.

Here is a screenshot of what I'm getting...


Here is the code I'm using to generate the brush and deform the terrain on click.


float paintSize = 0.01f;
int brushSize = 1;
const Ogre::uint arrayWidth = 16;

float* deltaArray = new float[arrayWidth * arrayWidth];

//float deltaArray[arrayWidth*arrayWidth];

for(int i=0; i < (arrayWidth*arrayWidth); i++)
deltaArray[i] = 1.0f;

GET_OGRE_SCENE->setOption("BrushScale", &paintSize);
GET_OGRE_SCENE->setOption("BrushSize", &brushSize);
GET_OGRE_SCENE->setOption("BrushArrayWidth", &arrayWidth);
GET_OGRE_SCENE->setOption("BrushArrayHeight", &arrayWidth);
GET_OGRE_SCENE->setOption("BrushArray", deltaArray);

Ogre::Vector3 center = mMouseNode->getPosition();
//GET_OGRE_SCENE->setOption("fillBrushArray", &center);
//GET_OGRE_SCENE->setOption("setHeightCenter", &center);
GET_OGRE_SCENE->setOption("DeformationCenter", &center);

delete deltaArray;


It appears to deform the terrain correctly on one side of the brush and not the other. The other side of the deformation stretches wildly off into the distance. I'm sure I'm doing something wrong here...just not sure what.

bibiteinfo

19-11-2007 15:16:37

Try this :


float paintSize = 0.01f;
int brushSize = 1;
const Ogre::uint arrayWidth = 16;

float* deltaArray = new float[arrayWidth * arrayWidth];

deltaArray[0] = 0.f;
deltaArray[arrayWidth * arrayWidth - 1] = 0.f;

for(int i=1; i < (arrayWidth*arrayWidth) - 1; i++)
deltaArray[i] = 1.0f;

GET_OGRE_SCENE->setOption("BrushScale", &paintSize);
GET_OGRE_SCENE->setOption("BrushSize", &brushSize);
GET_OGRE_SCENE->setOption("BrushArrayWidth", &arrayWidth);
GET_OGRE_SCENE->setOption("BrushArrayHeight", &arrayWidth);
GET_OGRE_SCENE->setOption("BrushArray", deltaArray);

Ogre::Vector3 center = mMouseNode->getPosition();
//GET_OGRE_SCENE->setOption("fillBrushArray", &center);
//GET_OGRE_SCENE->setOption("setHeightCenter", &center);
GET_OGRE_SCENE->setOption("DeformationCenter", &center);

delete deltaArray;



Maybe there's a problem with bounds.

danto

19-11-2007 21:33:35

Nope...still no luck. I agree that it seemed to be an array issue, but still not sure what. I appreciate your help...I'm going to start work on some other parts of my project and come back to paging landscapes later...perhaps when it's version 3...hehe. Thanks again.

jguerra

23-11-2007 16:38:22

Take a look at this post.
http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=5483

It's the same problem stated here with some more info and a reply from Tuan.
I haven't tried it yet on windows. Lot of work to do.... Going to do it probably next week.
I'll post the results then.