{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreidifxa6wxooxhpdwyzld5kffysdlmgvdr632ppynho5rrbkj4ytri",
    "uri": "at://did:plc:dxjzgxe7cvirxkwfjr2tjspt/app.bsky.feed.post/3mlwzwkljcps2"
  },
  "path": "/t/problem-between-tiles/49591#post_7",
  "publishedAt": "2026-05-16T01:12:15.000Z",
  "site": "https://hub.jmonkeyengine.org",
  "textContent": "\nwith wire frame would be like this, I prefer use wireframe off because is easy to spot holes where background is white on the black mesh.\n\nThe settings I use:\n`private AppSettingsConfig() { settings = new AppSettings(true); settings.setResolution( Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height ); settings.putInteger(\"MonitorIndex\", 1); settings.setTitle(\"jMonkeyEngine Game\"); settings.setDisplay(1); settings.setFrameRate(-1); settings.setVSync(false); settings.setFrequency(100); settings.setFullscreen(true); settings.setSamples(16); settings.setDepthBits(32); }`\n\nAfter comparing the values of rows and colums of the mesh and use mult instead of add , wich brings precision overtime each iteration. (The other program that creates the 16 bits images add sums in each iteration wich were giving wrong data, using multiplication fixed it)\n\nI had to change the scalar implementation to have the same cpu spets from SIMD pipeline, so it would compute the same numbers, and on the last col or row I use the value of next time instead of doing mutiplications.\n\n\n    static final float PLANET_RADIUS = 6371000f;\n    static final float STEP = (WorldConfig.TILE_LENGTH / (TILE_PIXELS - 1));\n    static final VectorSpecies FLOAT_VECTOR_SPECIES = FloatVector.SPECIES_PREFERRED;\n    static final VectorSpecies INT_SPECIES = IntVector.SPECIES_PREFERRED;\n    static final VectorSpecies SHORT_SPECIES = ShortVector.SPECIES_PREFERRED;\n\n    static final int TILE_PIXELS_BOUND_SHORT = SHORT_SPECIES.loopBound(WorldConfig.TILE_PIXELS);\n    static final int F_LENGTH = FLOAT_VECTOR_SPECIES.length();\n    static final int I_LENGTH = INT_SPECIES.length();\n    static final int S_LENGTH = SHORT_SPECIES.length();\n    static final int SHORT_VECTOR_LOOP_BOUND = TILE_PIXELS_BOUND_SHORT - S_LENGTH;\n    static final int INT_TO_FLOAT_GROUP_RATIO = INT_SPECIES.length() / F_LENGTH;\n    static final int SHORT_TO_INT_GROUP_RATIO = S_LENGTH / INT_SPECIES.length();\n    static final int TAIL_START_J = TILE_PIXELS_BOUND_SHORT;\n    static final int TAIL_LENGTH = TILE_PIXELS - TAIL_START_J;\n    static final FloatVector INDEX = FloatVector.fromArray(FLOAT_VECTOR_SPECIES, createIndex(), 0).mul(STEP);\n    static final float HEIGHT_SCALE = 3200.0f / (256f * 256f);\n    static final FloatVector ONE = FloatVector.broadcast(FLOAT_VECTOR_SPECIES, 1f);\n    static final float NORMALIZED_HEIGHT_SCALE = HEIGHT_SCALE / PLANET_RADIUS;\n    static final FloatVector NORMALIZED_HEIGHT_SCALE_VECTOR = FloatVector.broadcast(FLOAT_VECTOR_SPECIES, NORMALIZED_HEIGHT_SCALE);\n    static final float RADIUS_NORMALIZED_OFFSET = -200f / PLANET_RADIUS + 1f;\n    static final FloatVector RADIUS_NORMALIZED_OFFSET_VECTOR = FloatVector.broadcast(FLOAT_VECTOR_SPECIES, RADIUS_NORMALIZED_OFFSET);\n    private static final float\n     meshData = new float[TILE_PIXELS * TILE_PIXELS * 3];\n    static final short\n     shortArray = new short[TAIL_LENGTH];\n    static final float\n     tmp = new float[F_LENGTH * 3];\n    private static final ValueLayout.OfShort OF_SHORT = ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN);\n\n    private static float\n     createIndex() {\n    float\n     a = new float[F_LENGTH];\n    for (int i = 0; i < F_LENGTH; i++)\n    a[i] = i;\n    return a;\n    }\n\n    static float columnCord(short tileCol, int meshCol) {\n    if (meshCol == TILE_PIXELS - 1) {\n    return (tileCol + 1) * WorldConfig.TILE_LENGTH - GeoUtils.OFFSET;\n    }\n    return tileCol * WorldConfig.TILE_LENGTH - GeoUtils.OFFSET + STEP * meshCol;\n    }\n\n    static float rowCord(short tileRow, int meshRow) {\n    if (meshRow == TILE_PIXELS - 1) {\n    return (tileRow + 1) * WorldConfig.TILE_LENGTH - GeoUtils.OFFSET;\n    }\n    return tileRow * WorldConfig.TILE_LENGTH - GeoUtils.OFFSET + STEP * meshRow;\n    }\n\n    public static void writePositions(Tile tile) {\n    TileID tileId = tile.getTileId();\n    GeoEnum face = tileId.face();\n    MeshBuffer buffer = tile.getBuffer();\n    MemorySegment heightMap = HeightMapReader.getInstance().getMapData(tileId);\n    CubePlane plane = switch (face) {\n    case TOP, BOTTOM → CubePlane.HORIZONTAL;\n    case FRONT, BACK → CubePlane.FRONTAL;\n    case LEFT, RIGHT → CubePlane.PERFIL;\n    };\n    writePlane(tileId, tile.start(), heightMap, plane);\n    buffer.setPositionData(meshData);\n    }\n\n    static void writePlane(TileID tileId, Position3D start, MemorySegment heightMap, CubePlane layout) {\n    short tileRow = tileId.row();\n    short tileCol = tileId.col();\n    float f = layout.fixedBase(start);\n    FloatVector fixedVec = FloatVector.broadcast(FLOAT_VECTOR_SPECIES, f);\n    int offset = 0;\n    for (int i = 0; i < TILE_PIXELS; i++) {\n    float r = rowCord(tileRow, i);\n    FloatVector rowVec = FloatVector.broadcast(FLOAT_VECTOR_SPECIES, r);\n    for (int j = 0; j <= SHORT_VECTOR_LOOP_BOUND; j += S_LENGTH) {\n    ShortVector heightVec = ShortVector.fromMemorySegment(SHORT_SPECIES, heightMap, ((long) i * TILE_PIXELS + j) * Short.BYTES, ByteOrder.LITTLE_ENDIAN);\n    for (int k = 0; k < SHORT_TO_INT_GROUP_RATIO; k++) {\n    IntVector unsigned = (IntVector) heightVec.convertShape(VectorOperators.S2I, INT_SPECIES, k).lanewise(VectorOperators.AND, 0xFFFF);\n    for (int h = 0; h < INT_TO_FLOAT_GROUP_RATIO; h++) {\n    int colStart = j + k * I_LENGTH + h * F_LENGTH;\n    FloatVector colVec = INDEX.add( columnCord(tileCol, colStart));\n    FloatVector fv = (FloatVector) unsigned.convertShape(VectorOperators.I2F, FLOAT_VECTOR_SPECIES, h);\n    FloatVector heightVecNormalized = fv.fma(NORMALIZED_HEIGHT_SCALE_VECTOR, RADIUS_NORMALIZED_OFFSET_VECTOR);\n    FloatVector xVec = layout.wx(fixedVec, rowVec, colVec);\n    FloatVector yVec = layout.wy(fixedVec, rowVec, colVec);\n    FloatVector zVec = layout.wz(fixedVec, rowVec, colVec);\n    FloatVector len = xVec.fma(xVec, yVec.fma(yVec, zVec.mul(zVec)));\n    FloatVector invLen = ONE.div(len.sqrt()).mul(heightVecNormalized);\n    FloatVector nx = xVec.mul(invLen);\n    FloatVector ny = yVec.mul(invLen);\n    FloatVector nz = zVec.mul(invLen);\n    nx.intoArray(tmp, 0);\n    ny.intoArray(tmp, F_LENGTH);\n    nz.intoArray(tmp, F_LENGTH * 2);\n    for (int lane = 0; lane < F_LENGTH; lane++) {\n    meshData[offset++] = tmp[lane];\n    meshData[offset++] = tmp[lane + F_LENGTH];\n    meshData[offset++] = tmp[lane + F_LENGTH * 2];\n\n                    }\n                }\n            }\n        }\n        long tailOffsetBytes = ((long) i * TILE_PIXELS + TAIL_START_J) * Short.BYTES;\n        MemorySegment.copy(heightMap, ValueLayout.JAVA_SHORT_UNALIGNED.withOrder(ByteOrder.LITTLE_ENDIAN), tailOffsetBytes, shortArray, 0, TAIL_LENGTH);\n        for (int s = TAIL_START_J; s < TILE_PIXELS; s++) {\n            float c = columnCord(tileCol, s);\n            float wx = layout.sx(f, r, c);\n            float wy = layout.sy(f, r, c);\n            float wz = layout.sz(f, r, c);\n            int u = Short.toUnsignedInt(shortArray[s - TAIL_START_J]);\n            float len = (float) Math.sqrt(Math.fma(wx, wx, Math.fma(wy, wy, wz * wz)));\n            float height = Math.fma(u, NORMALIZED_HEIGHT_SCALE, RADIUS_NORMALIZED_OFFSET);\n            float inv = 1f / len * height;\n            meshData[offset++] = wx * inv;\n            meshData[offset++] = wy * inv;\n            meshData[offset++] = wz * inv;\n        }\n    }\n\n    }\n\n\nThanks to all.",
  "title": "Problem between tiles"
}