angros47 / OpenB3D

GNU Lesser General Public License v2.1
1 stars 0 forks source link

Terrain Creation Issue #10

Closed blitzcoder closed 1 year ago

blitzcoder commented 1 year ago

When Blitz3D loads a terrain, the terrain is always flat or at original scale.

LoadTerrain should not determine the height and it should be user defined with ScaleEntity.

Terrain x and z initial sizes are also smaller compared to B3D counter part.

angros47 commented 1 year ago

The height, in LoadTerrain, is determined by the brightness of the pixel in the map picture, that can range from 0 to 255. Internally, the value is stored in the "height" array, that is a float and can range from 0 to 1. When the terrain is rendered, that value is multiplied by vsize, that by default is set to 30, and then to the scale factor. The variable vsize is set inside the function CreateTerrain, so if you change the line:

terr->vsize=30;

to

terr->vsize=1;

You should achieve the same behavior of Blitz3D. Let me know if it works (I wouldn't consider this issue a bug, only a difference from Blitz3D)

blitzcoder commented 1 year ago

Yes, that seem to achieve the same behavior with vsize to 1, but this actually points to and linked with TerrainY and Scaled Terrains, might apply to TerrainX and TerrainZ as well.

angros47 commented 1 year ago

What is the issue you have with TerrainX, TerrainZ and TerrainY?

blitzcoder commented 1 year ago

What is the issue you have with TerrainX, TerrainZ and TerrainY?

It's not working when the terrain is scaled: https://github.com/angros47/OpenB3D/issues/9

TerrainY in particular.

angros47 commented 1 year ago

I have a suspect of what can cause the bug. Do this experiment: if you have a line like

TerrainY(terrain, x, y, z)

replace it with

TerrainY(terrain, x, y, -z)

(obviously, if you have any other expression or variable in place of z, just change its sign in the same way). Check if it works as expected, in this way, at least for a terrain in position 0,0,0 and not rotated

angros47 commented 1 year ago

Also, test if, in terrain.cpp, this patch may help:

float Terrain::TerrainY (float x, float y, float z){ TFormPoint(x, y, z, 0, this); float p0[3],p1[3],p2[3]; p0[0]=(int)tformed_x; p0[2]=(int)-tformed_z; p0[1]=height[(int)((int)tformed_xsize-tformed_z)] vsize;

p2[0]=(int)tformed_x+1;
p2[2]=(int)-tformed_z;
p2[1]=height[(int)(((int)(tformed_x+1)*size)- tformed_z)] * vsize;

if (tformed_x-floor(tformed_x)-tformed_z+floor(tformed_z)<.5){
    p1[0]=(int)tformed_x;
    p1[2]=(int)-tformed_z-1;
    p1[1]=height[(int)(((int)tformed_x*size)- tformed_z-1)] * vsize;
}else
{
    p1[0]=(int)tformed_x+1;
    p1[2]=(int)-tformed_z-1;
    p1[1]=height[(int)(((int)(tformed_x+1)*size)- tformed_z-1)] * vsize;
}

float A = p0[1] *(p1[2] - p2[2]) + p1[1] *(p2[2] - p0[2]) + p2[1] *(p0[2] - p1[2]);
float B = p0[2] *(p1[0] - p2[0]) + p1[2] *(p2[0] - p0[0]) + p2[2] *(p0[0] - p1[0]);
float C = p0[0] *(p1[1] - p2[1]) + p1[0] *(p2[1] - p0[1]) + p2[0] *(p0[1] - p1[1]);
float D = -(p0[0] *(p1[1] * p2[2] - p2[1] * p1[2]) + p1[0] *(p2[1]* p0[2] - p0[1]* p2[2]) + p2[0] *(p0[1] *p1[2] - p1[1] *p0[2]));
if (B==0.0) B=0.0001;
return -(D+A*tformed_x-C*tformed_z)/B;

}

float Terrain::TerrainZ (float x, float y, float z){ TFormPoint(x, y, z, 0, this); return -tformed_z; }

(I haven't tested it, but it might be related with the issue you are talking about)

blitzcoder commented 1 year ago

I did apply the cpp changes, but still the same result with TerrainY not getting accurate ground height when scaled.

angros47 commented 1 year ago

Just to be sure: if terrain is NOT scaled, but it is moved and/or rotated, do TerrainX, TerrainY and TerrainZ return the expected result? (with the original version, or with the patched version?) If the terrain is scaled, does the scaling affect only TerrainY, or all? And what happens if you scale the terrain on x and z axis, but not on y?

angros47 commented 1 year ago

Also: by multiplying the result of TerrainY with EntityScaleY(terrain, true) do you get the correct value?

blitzcoder commented 1 year ago

Yes, this seems to solve the problem and same with X and Z to show correct results, closing related issue #9

angros47 commented 1 year ago

So, please let me know: X and Z show the correct values with or without the patch? And Y shows the correct value (after multiplying it with the scale factor) with or without the patch? So I can fix the official version

blitzcoder commented 1 year ago

reverted back and nothing to do with previous solutions, just multiplying TerrainY with EntityScaleY, applies the same with X and Z.

angros47 commented 1 year ago

So, terrainX, terrainy and terrainz have to be multiplied by EntityScaleX/Y/Z to behave like in Blitz3D?

blitzcoder commented 1 year ago

Yes, that should do it.

to behave like in Blitz3D?

It's the only way, unless you don't use TerrainY or other possible affected commands with a Scaled Terrain which seems to be a rare case.

angros47 commented 1 year ago

Then, I would not consider it an issue, but just another difference from Blitz3D. In my opinion, in fact, would make more sense to have the TerrainX and TerrainZ referring to the unscaled terrain, so they could be easily used as coordinates for ModifyTerrain (for example, to lower the terrain under the player when the player is digging). And of course, TerrainY should refer to unscaled terrain, too, for consistence

blitzcoder commented 1 year ago

No problem, the main thing is it's related and the issue has been pointed out and resolved. Thanks and closing.