Java Code Examples for com.jme3.scene.Spatial#updateModelBound()

The following examples show how to use com.jme3.scene.Spatial#updateModelBound() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: GeomUtils.java    From jmonkeybuilder with Apache License 2.0 5 votes vote down vote up
/**
 * Get a collision on spatial from screen position.
 *
 * @param spatial the spatial.
 * @param camera  the camera.
 * @param screenX the screen X coord.
 * @param screenY the screen Y coord.
 * @return the collisions .
 */
@FromAnyThread
public static @NotNull CollisionResults getCollisionsFromScreenPos(
        @NotNull Spatial spatial,
        @NotNull Camera camera,
        float screenX,
        float screenY
) {

    var local = LocalObjects.get();

    var cursor = local.nextVector(screenX, screenY);
    var click3d = camera.getWorldCoordinates(cursor, 0f, local.nextVector());
    var dir = camera.getWorldCoordinates(cursor, 1f, local.nextVector())
            .subtractLocal(click3d)
            .normalizeLocal();

    var ray = local.nextRay();
    ray.setOrigin(click3d);
    ray.setDirection(dir);

    var results = local.nextCollisionResults();

    spatial.updateModelBound();
    spatial.collideWith(ray, results);

    return results;
}
 
Example 2
Source File: RoughTerrainToolControl.java    From jmonkeybuilder with Apache License 2.0 4 votes vote down vote up
/**
 * Modify height of terrain points.
 *
 * @param contactPoint the contact point.
 */
@JmeThread
private void modifyHeight(@NotNull final Vector3f contactPoint) {

    final LocalObjects local = getLocalObjects();
    final Spatial paintedModel = notNull(getPaintedModel());
    final Geometry brush = getBrush();

    final float brushSize = getBrushSize();
    final int twoBrushSize = (int) (brushSize * 2);

    final Basis fractalFilter = createFractalGenerator();
    final List<Vector2f> locs = new ArrayList<>();
    final List<Float> heights = new ArrayList<>();

    for (final Terrain terrain : getTerrains()) {

        final Node terrainNode = (Node) terrain;

        locs.clear();
        heights.clear();

        final Vector3f worldTranslation = terrainNode.getWorldTranslation();
        final Vector3f localScale = terrainNode.getLocalScale();
        final Vector3f localPoint = contactPoint.subtract(worldTranslation, local.nextVector());
        final Vector2f terrainLoc = local.nextVector2f();
        final Vector2f effectPoint = local.nextVector2f();

        final FloatBuffer buffer = fractalFilter.getBuffer(terrainLoc.getX(), terrainLoc.getY(), 0, twoBrushSize);

        final int radiusStepsX = (int) (brushSize / localScale.getX());
        final int radiusStepsZ = (int) (brushSize / localScale.getY());

        final float xStepAmount = localScale.getX();
        final float zStepAmount = localScale.getZ();

        for (int z = -radiusStepsZ, yfb = 0; z < radiusStepsZ; z++, yfb++) {
            for (int x = -radiusStepsX, xfb = 0; x < radiusStepsX; x++, xfb++) {

                final float locX = localPoint.getX() + (x * xStepAmount);
                final float locZ = localPoint.getZ() + (z * zStepAmount);

                effectPoint.set(locX - localPoint.getX(), locZ - localPoint.getZ());

                if (!isContains(brush, effectPoint.getX(), effectPoint.getX())) {
                    continue;
                }

                final float height = buffer.get(yfb * twoBrushSize + xfb);

                terrainLoc.set(locX, locZ);

                final float heightmapHeight = terrain.getHeightmapHeight(terrainLoc);
                if (Float.isNaN(heightmapHeight)) {
                    continue;
                }

                final float currentHeight = heightmapHeight * localScale.getY();
                // see if it is in the radius of the tool
                final float newHeight = calculateHeight(brushSize, height, effectPoint);

                locs.add(terrainLoc.clone());
                heights.add(currentHeight + newHeight);
            }
        }

        locs.forEach(location -> change(terrain, location));

        // do the actual height adjustment
        terrain.setHeight(locs, heights);
    }

    // or else we won't collide with it where we just edited
    paintedModel.updateModelBound();
}
 
Example 3
Source File: RaiseLowerTerrainToolControl.java    From jmonkeybuilder with Apache License 2.0 4 votes vote down vote up
/**
 * Modify height of terrain points.
 *
 * @param input the type of input.
 * @param contactPoint the contact point.
 */
@JmeThread
private void modifyHeight(@NotNull final PaintingInput input, @NotNull final Vector3f contactPoint) {

    final LocalObjects local = getLocalObjects();
    final Spatial paintedModel = notNull(getPaintedModel());
    final Geometry brush = getBrush();

    final float brushSize = getBrushSize();
    final float brushPower = input == PaintingInput.MOUSE_PRIMARY ? getBrushPower() : getBrushPower() * -1F;

    final List<Vector2f> locs = new ArrayList<>();
    final List<Float> heights = new ArrayList<>();

    for (final Terrain terrain : getTerrains()) {

        final Node terrainNode = (Node) terrain;

        locs.clear();
        heights.clear();

        final Vector3f worldTranslation = terrainNode.getWorldTranslation();
        final Vector3f localScale = terrainNode.getLocalScale();
        final Vector3f localPoint = contactPoint.subtract(worldTranslation, local.nextVector());
        final Vector2f terrainLoc = local.nextVector2f();
        final Vector2f effectPoint = local.nextVector2f();

        final int radiusStepsX = (int) (brushSize / localScale.getX());
        final int radiusStepsZ = (int) (brushSize / localScale.getY());

        final float xStepAmount = localScale.getX();
        final float zStepAmount = localScale.getZ();

        for (int z = -radiusStepsZ; z < radiusStepsZ; z++) {
            for (int x = -radiusStepsX; x < radiusStepsX; x++) {

                float locX = localPoint.getX() + (x * xStepAmount);
                float locZ = localPoint.getZ() + (z * zStepAmount);

                effectPoint.set(locX - localPoint.getX(), locZ - localPoint.getZ());

                if (!isContains(brush, effectPoint.getX(), effectPoint.getY())) {
                    continue;
                }

                terrainLoc.set(locX, locZ);

                final float heightmapHeight = terrain.getHeightmapHeight(terrainLoc);
                if (Float.isNaN(heightmapHeight)) {
                    continue;
                }

                final float currentHeight = heightmapHeight * localScale.getY();
                // adjust height based on radius of the tool
                final float newHeight = calculateHeight(brushSize, brushPower, effectPoint.getX(), effectPoint.getY());

                // increase the height
                locs.add(terrainLoc.clone());
                heights.add(currentHeight + newHeight);
            }
        }

        locs.forEach(location -> change(terrain, location));
        // do the actual height adjustment
        terrain.setHeight(locs, heights);
    }

    // or else we won't collide with it where we just edited
    paintedModel.updateModelBound();
}
 
Example 4
Source File: SpawnToolControl.java    From jmonkeybuilder with Apache License 2.0 4 votes vote down vote up
/**
 * Spawn models.
 *
 * @param brushRotation the brush rotation.
 * @param contactPoint  the contact point.
 */
@JmeThread
protected void spawn(@NotNull Quaternion brushRotation, @NotNull Vector3f contactPoint) {

    var brushSize = getBrushSize();

    var random = ThreadLocalRandom.current();
    var local = getLocalObjects();
    var spawnPosition = local.nextVector();

    var paintedModel = getPaintedModel();
    var direction = GeomUtils.getDirection(brushRotation, local.nextVector())
            .negateLocal()
            .multLocal(10);

    var sourcePoint = contactPoint.subtract(direction, local.nextVector());
    var ray = local.nextRay();
    ray.setOrigin(sourcePoint);

    var minScale = getMinScale();
    var maxScale = getMaxScale();
    var padding = getPadding();

    var resultPosition = local.nextVector();
    var collisions = local.nextCollisionResults();
    var spawnedCollisions = local.nextCollisionResults();
    var resultScale = local.nextVector();
    var needCalculateScale = !minScale.equals(maxScale);

    var maxCount = (int) Math.max(getBrushPower() / 2F, 1F);
    var spawnedModels = getSpawnedModels();

    for(var count = 0; count < maxCount; count++) {
        for (var attempts = 0; attempts < 10; attempts++, attempts++) {

            collisions.clear();
            spawnedCollisions.clear();

            var x = nextOffset(brushSize, random);
            var y = nextOffset(brushSize, random);
            var z = nextOffset(brushSize, random);

            spawnPosition.set(x, y, z)
                    .addLocal(contactPoint)
                    .subtractLocal(sourcePoint)
                    .normalizeLocal();

            ray.setDirection(spawnPosition);

            paintedModel.collideWith(ray, collisions);

            var closest = collisions.getClosestCollision();
            if (closest == null || contactPoint.distance(closest.getContactPoint()) > brushSize / 2) {
                continue;
            }

            resultPosition.set(closest.getContactPoint())
                    .subtractLocal(paintedModel.getWorldTranslation());

            Spatial clone = examples.get(random.nextInt(0, examples.size())).clone();
            clone.setUserData(KEY_IGNORE_RAY_CAST, Boolean.TRUE);
            clone.setLocalTranslation(resultPosition);

            if (needCalculateScale) {
                clone.setLocalScale(nextScale(minScale, maxScale, resultScale, random));
            } else {
                clone.setLocalScale(minScale);
            }

            clone.updateModelBound();

            var worldBound = clone.getWorldBound();

            if (!Vector3f.ZERO.equals(padding)) {
                worldBound = addPadding(worldBound, padding);
            }

            if (paintedModel.collideWith(worldBound, spawnedCollisions) > 2) {
                continue;
            }

            spawnedModels.add(clone);
            paintedModel.attachChild(clone);
            break;
        }
    }
}