Java Code Examples for com.jme3.math.Vector3f#subtract()

The following examples show how to use com.jme3.math.Vector3f#subtract() . 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: OpaqueComparator.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public float distanceToCam(Geometry spat){
    if (spat == null)
        return Float.NEGATIVE_INFINITY;
 
    if (spat.queueDistance != Float.NEGATIVE_INFINITY)
            return spat.queueDistance;
 
    Vector3f camPosition = cam.getLocation();
    Vector3f viewVector = cam.getDirection(tempVec2);
    Vector3f spatPosition = null;
 
    if (spat.getWorldBound() != null){
        spatPosition = spat.getWorldBound().getCenter();
    }else{
        spatPosition = spat.getWorldTranslation();
    }
 
    spatPosition.subtract(camPosition, tempVec);
    spat.queueDistance = tempVec.dot(viewVector);
 
    return spat.queueDistance;
}
 
Example 2
Source File: SkeletonInterBoneWire.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
/**
 * The method updates the geometry according to the poitions of the bones.
 */
public void updateGeometry() {
    VertexBuffer vb = this.getBuffer(Type.Position);
    FloatBuffer posBuf = this.getFloatBuffer(Type.Position);
    posBuf.clear();
    for (int i = 0; i < skeleton.getBoneCount(); ++i) {
        Bone bone = skeleton.getBone(i);
        Vector3f parentTail = bone.getModelSpacePosition().add(bone.getModelSpaceRotation().mult(Vector3f.UNIT_Y.mult(boneLengths.get(i))));

        for (Bone child : bone.getChildren()) {
            Vector3f childHead = child.getModelSpacePosition();
            Vector3f v = childHead.subtract(parentTail);
            float pointDelta = v.length() / POINT_AMOUNT;
            v.normalizeLocal().multLocal(pointDelta);
            Vector3f pointPosition = parentTail.clone();
            for (int j = 0; j < POINT_AMOUNT; ++j) {
                posBuf.put(pointPosition.getX()).put(pointPosition.getY()).put(pointPosition.getZ());
                pointPosition.addLocal(v);
            }
        }
    }
    posBuf.flip();
    vb.updateData(posBuf);

    this.updateBound();
}
 
Example 3
Source File: TransparentComparator.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * Calculates the distance from a spatial to the camera. Distance is a
 * squared distance.
 *
 * @param spat
 *            Spatial to distancize.
 * @return Distance from Spatial to camera.
 */
private float distanceToCam2(Geometry spat){
    if (spat == null)
        return Float.NEGATIVE_INFINITY;

    if (spat.queueDistance != Float.NEGATIVE_INFINITY)
        return spat.queueDistance;

    Vector3f camPosition = cam.getLocation();
    Vector3f viewVector = cam.getDirection();
    Vector3f spatPosition = null;

    if (spat.getWorldBound() != null){
        spatPosition = spat.getWorldBound().getCenter();
    }else{
        spatPosition = spat.getWorldTranslation();
    }

    spatPosition.subtract(camPosition, tempVec);
    spat.queueDistance = tempVec.dot(tempVec);

    float retval = Math.abs(tempVec.dot(viewVector)
            / viewVector.dot(viewVector));
    viewVector.mult(retval, tempVec);

    spat.queueDistance = tempVec.length();

    return spat.queueDistance;
}
 
Example 4
Source File: TransparentComparator.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Calculates the distance from a spatial to the camera. Distance is a
 * squared distance.
 *
 * @param spat
 *            Spatial to distancize.
 * @return Distance from Spatial to camera.
 */
private float distanceToCam2(Geometry spat){
    if (spat == null)
        return Float.NEGATIVE_INFINITY;

    if (spat.queueDistance != Float.NEGATIVE_INFINITY)
        return spat.queueDistance;

    Vector3f camPosition = cam.getLocation();
    Vector3f viewVector = cam.getDirection();
    Vector3f spatPosition = null;

    if (spat.getWorldBound() != null){
        spatPosition = spat.getWorldBound().getCenter();
    }else{
        spatPosition = spat.getWorldTranslation();
    }

    spatPosition.subtract(camPosition, tempVec);
    spat.queueDistance = tempVec.dot(tempVec);

    float retval = Math.abs(tempVec.dot(viewVector)
            / viewVector.dot(viewVector));
    viewVector.mult(retval, tempVec);

    spat.queueDistance = tempVec.length();

    return spat.queueDistance;
}
 
Example 5
Source File: Slider.java    From Lemur with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 *  Returns the slider range value for the specified location
 *  in the slider's local coordinate system.  (For example,
 *  for world space location use slider.worldToLocal() first.)
 */
public double getValueForLocation( Vector3f loc ) {

    Vector3f relative = loc.subtract(range.getLocalTranslation());

    // Components always grow down from their location
    // so we'll invert y
    relative.y *= -1;
            
    Vector3f axisDir = axis.getDirection();
    double projection = relative.dot(axisDir);
    if( projection < 0 ) {
        if( axis == Axis.Y ) {
            return model.getMaximum();
        } else {
            return model.getMinimum();
        }
    }
    
    Vector3f rangeSize = range.getSize().clone();
     
    double rangeLength = rangeSize.dot(axisDir);
    projection = Math.min(projection, rangeLength);
    double part = projection / rangeLength;       
    double rangeDelta = model.getMaximum() - model.getMinimum();
    
    // For the y-axis, the slider is inverted from the direction
    // that the component's grow... so our part is backwards
    if( axis == Axis.Y ) {
        part = 1 - part;
    }
 
    return model.getMinimum() + rangeDelta * part;        
}
 
Example 6
Source File: SpotLight.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
@Override
public boolean intersectsBox(BoundingBox box, TempVars vars) {
    if (this.spotRange > 0f) {
        // Check spot range first.
        // Sphere v. box collision
        if (!Intersection.intersect(box, position, spotRange)) {
            return false;
        }
    }
    
    Vector3f otherCenter = box.getCenter();
    Vector3f radVect = vars.vect4;
    radVect.set(box.getXExtent(), box.getYExtent(), box.getZExtent());
    float otherRadiusSquared = radVect.lengthSquared();
    float otherRadius = FastMath.sqrt(otherRadiusSquared);
    
    // Check if sphere is within spot angle.
    // Cone v. sphere collision.
    Vector3f E = direction.mult(otherRadius * outerAngleSinRcp, vars.vect1);
    Vector3f U = position.subtract(E, vars.vect2);
    Vector3f D = otherCenter.subtract(U, vars.vect3);

    float dsqr = D.dot(D);
    float e = direction.dot(D);

    if (e > 0f && e * e >= dsqr * outerAngleCosSqr) {
        D = otherCenter.subtract(position, vars.vect3);
        dsqr = D.dot(D);
        e = -direction.dot(D);

        if (e > 0f && e * e >= dsqr * outerAngleSinSqr) {
            return dsqr <= otherRadiusSquared;
        } else {
            return true;
        }
    }
    
    return false;
}
 
Example 7
Source File: TestIssue1283.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Add a projectile to the scene and physics space. Its initial position and
 * velocity are determined by the camera the and mouse pointer.
 */
private void launchProjectile() {
    Vector2f screenXY = inputManager.getCursorPosition();
    float nearZ = 0f;
    Vector3f nearLocation = cam.getWorldCoordinates(screenXY, nearZ);
    float farZ = 1f;
    Vector3f farLocation = cam.getWorldCoordinates(screenXY, farZ);
    Vector3f direction = farLocation.subtract(nearLocation);
    direction.normalizeLocal();

    Geometry geometry = new Geometry("projectile", projectileMesh);
    rootNode.attachChild(geometry);
    geometry.setLocalTranslation(nearLocation);
    geometry.setMaterial(projectileMaterial);

    float mass = 1f;
    RigidBodyControl physicsControl = new RigidBodyControl(mass);
    geometry.addControl(physicsControl);

    physicsControl.setCcdMotionThreshold(0.01f);
    physicsControl.setCcdSweptSphereRadius(projectileRadius);
    physicsControl.setCollisionGroup(
            PhysicsCollisionObject.COLLISION_GROUP_02);
    physicsControl.setCollideWithGroups(
            PhysicsCollisionObject.COLLISION_GROUP_02);
    physicsControl.setRestitution(0.8f);

    float projectileSpeed = 250f; // physics-space units per second
    Vector3f initialVelocity = direction.mult(projectileSpeed);
    physicsControl.setLinearVelocity(initialVelocity);

    physicsSpace.add(physicsControl);
}
 
Example 8
Source File: ObstacleAvoidanceBehavior.java    From MonkeyBrains with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
/**
 * Generates a random vector inside a plane defined by a normal vector and a
 * point
 */
protected Vector3f randomVectInPlane(Vector3f planeNormalV, Vector3f planePoint) {
    Random rand = FastMath.rand;

    /* Plane ecuation: Ax + By + Cz + D = 0 
     *  => z = -(Ax + By + D) / C
     *  => x = -(By + Cz + D) / A
     *  => y = -(Ax + Cz + D) / B
     */
    float a = planeNormalV.x;
    float b = planeNormalV.y;
    float c = planeNormalV.z;
    float d = -((a * planePoint.x)
            + (b * planePoint.y)
            + (c * planePoint.z));

    float x, y, z;

    if (c != 0) {
        x = rand.nextFloat();
        y = rand.nextFloat();
        z = -((a * x) + (b * y) + d) / c;
    } else if (a != 0) {
        y = rand.nextFloat();
        z = rand.nextFloat();
        x = -((b * y) + (c * z) + d) / a;
    } else if (b != 0) {
        x = rand.nextFloat();
        z = rand.nextFloat();
        y = -((a * x) + (c * z) + d) / b;
    } else {
        x = rand.nextFloat();
        y = rand.nextFloat();
        z = rand.nextFloat();
    }

    Vector3f randPoint = new Vector3f(x, y, z);

    return randPoint.subtract(planePoint);
}
 
Example 9
Source File: BoxExploreBehavior.java    From MonkeyBrains with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
private void construct(Vector3f boxCenter, float boxWidthX, float boxWidthZ, float boxHeight, float subdivisionDistance) {
    if (boxWidthX < 0 || boxWidthZ < 0 || boxHeight < 0) {
        throw new SteeringExceptions.NegativeValueException("Box width, depth and height must be positive.");
    } else if (subdivisionDistance <= 0) {
        throw new SteeringExceptions.NegativeValueException("The subdivision distance must be higher than 0.");
    }

    this.boxWidthX = boxWidthX;
    this.boxWidthZ = boxWidthZ;
    this.boxHeight = boxHeight;
    this.subdivisionDistance = subdivisionDistance;
    this.zeroCorner = boxCenter.subtract(new Vector3f(this.boxHeight / 2, this.boxHeight / 2, this.boxWidthZ / 2));
    this.addNewTargets();
}
 
Example 10
Source File: CurvesHelper.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 5 votes vote down vote up
/**
 * The method transforms the bevel along the curve.
 * 
 * @param bevel
 *            the bevel to be transformed
 * @param prevPos
 *            previous curve point
 * @param currPos
 *            current curve point (here the center of the new bevel will be
 *            set)
 * @param nextPos
 *            next curve point
 * @return points of transformed bevel
 */
private Vector3f[] transformBevel(Vector3f[] bevel, Vector3f prevPos, Vector3f currPos, Vector3f nextPos) {
    bevel = bevel.clone();

    // currPos and directionVector define the line in 3D space
    Vector3f directionVector = prevPos != null ? currPos.subtract(prevPos) : nextPos.subtract(currPos);
    directionVector.normalizeLocal();

    // plane is described by equation: Ax + By + Cz + D = 0 where planeNormal = [A, B, C] and D = -(Ax + By + Cz)
    Vector3f planeNormal = null;
    if (prevPos != null) {
        planeNormal = currPos.subtract(prevPos).normalizeLocal();
        if (nextPos != null) {
            planeNormal.addLocal(nextPos.subtract(currPos).normalizeLocal()).normalizeLocal();
        }
    } else {
        planeNormal = nextPos.subtract(currPos).normalizeLocal();
    }
    float D = -planeNormal.dot(currPos);// D = -(Ax + By + Cz)

    // now we need to compute paralell cast of each bevel point on the plane, the leading line is already known
    // parametric equation of a line: x = px + vx * t; y = py + vy * t; z = pz + vz * t
    // where p = currPos and v = directionVector
    // using x, y and z in plane equation we get value of 't' that will allow us to compute the point where plane and line cross
    float temp = planeNormal.dot(directionVector);
    for (int i = 0; i < bevel.length; ++i) {
        float t = -(planeNormal.dot(bevel[i]) + D) / temp;
        if (fixUpAxis) {
            bevel[i] = new Vector3f(bevel[i].x + directionVector.x * t, bevel[i].y + directionVector.y * t, bevel[i].z + directionVector.z * t);
        } else {
            bevel[i] = new Vector3f(bevel[i].x + directionVector.x * t, -bevel[i].z + directionVector.z * t, bevel[i].y + directionVector.y * t);
        }
    }
    return bevel;
}
 
Example 11
Source File: TriangulatedTexture.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
/**
 * Constructor that creates an image element from the 3D texture
 * (generated texture). It computes a flat smallest rectangle that can
 * hold a (3D) triangle defined by the given UV coordinates. Then it
 * defines the image pixels for points in 3D space that define the
 * calculated rectangle.
 * 
 * @param faceIndex
 *            the face index this image refers to
 * @param boundingBox
 *            the bounding box of the mesh
 * @param texture
 *            the texture that allows to compute a pixel value in 3D
 *            space
 * @param uv
 *            the UV coordinates of the mesh
 * @param blenderContext
 *            the blender context
 */
public TriangleTextureElement(int faceIndex, BoundingBox boundingBox, GeneratedTexture texture, Vector3f[] uv, int[] uvIndices, BlenderContext blenderContext) {
    this.faceIndex = faceIndex;

    // compute the face vertices from the UV coordinates
    float width = boundingBox.getXExtent() * 2;
    float height = boundingBox.getYExtent() * 2;
    float depth = boundingBox.getZExtent() * 2;

    Vector3f min = boundingBox.getMin(null);
    Vector3f v1 = min.add(uv[uvIndices[0]].x * width, uv[uvIndices[0]].y * height, uv[uvIndices[0]].z * depth);
    Vector3f v2 = min.add(uv[uvIndices[1]].x * width, uv[uvIndices[1]].y * height, uv[uvIndices[1]].z * depth);
    Vector3f v3 = min.add(uv[uvIndices[2]].x * width, uv[uvIndices[2]].y * height, uv[uvIndices[2]].z * depth);

    // get the rectangle envelope for the triangle
    RectangleEnvelope envelope = this.getTriangleEnvelope(v1, v2, v3);

    // create the result image
    Format imageFormat = texture.getImage().getFormat();
    int imageWidth = (int) (envelope.width * blenderContext.getBlenderKey().getGeneratedTexturePPU());
    if (imageWidth == 0) {
        imageWidth = 1;
    }
    int imageHeight = (int) (envelope.height * blenderContext.getBlenderKey().getGeneratedTexturePPU());
    if (imageHeight == 0) {
        imageHeight = 1;
    }
    ByteBuffer data = BufferUtils.createByteBuffer(imageWidth * imageHeight * (imageFormat.getBitsPerPixel() >> 3));
    image = new Image(texture.getImage().getFormat(), imageWidth, imageHeight, data);

    // computing the pixels
    PixelInputOutput pixelWriter = PixelIOFactory.getPixelIO(imageFormat);
    TexturePixel pixel = new TexturePixel();
    float[] uvs = new float[3];
    Vector3f point = new Vector3f(envelope.min);
    Vector3f vecY = new Vector3f();
    Vector3f wDelta = new Vector3f(envelope.w).multLocal(1.0f / imageWidth);
    Vector3f hDelta = new Vector3f(envelope.h).multLocal(1.0f / imageHeight);
    for (int x = 0; x < imageWidth; ++x) {
        for (int y = 0; y < imageHeight; ++y) {
            this.toTextureUV(boundingBox, point, uvs);
            texture.getPixel(pixel, uvs[0], uvs[1], uvs[2]);
            pixelWriter.write(image, 0, pixel, x, y);
            point.addLocal(hDelta);
        }

        vecY.addLocal(wDelta);
        point.set(envelope.min).addLocal(vecY);
    }

    // preparing UV coordinates for the flatted texture
    this.uv = new Vector2f[3];
    this.uv[0] = new Vector2f(FastMath.clamp(v1.subtract(envelope.min).length(), 0, Float.MAX_VALUE) / envelope.height, 0);
    Vector3f heightDropPoint = v2.subtract(envelope.w);// w is directed from the base to v2
    this.uv[1] = new Vector2f(1, heightDropPoint.subtractLocal(envelope.min).length() / envelope.height);
    this.uv[2] = new Vector2f(0, 1);
}
 
Example 12
Source File: PathFollowBehavior.java    From MonkeyBrains with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * @see AbstractStrengthSteeringBehavior#calculateRawSteering()
 */
@Override
protected Vector3f calculateRawSteering() {
    Vector3f steer = new Vector3f();

    if (active) {
        //Start to follow from the beginning
        if (this.nextSpineJoint < 0) {
            this.nextSpineJoint = 0;
        }

        if (this.nextSpineJoint < this.orderedPointsList.size()) {
            //Calculate the next exit
            Vector3f exitNormal;
            if (this.nextSpineJoint == 0) {
                exitNormal = this.orderedPointsList.get(this.nextSpineJoint + 1).subtract(this.orderedPointsList.get(this.nextSpineJoint));
            } else {
                exitNormal = this.orderedPointsList.get(this.nextSpineJoint).subtract(this.orderedPointsList.get(this.nextSpineJoint - 1));
            }

            this.nextExit = new Plane();
            this.nextExit.setOriginNormal(
                    this.orderedPointsList.get(this.nextSpineJoint),
                    exitNormal);

            Vector3f posProjection = this.nextExit.getClosestPoint(this.agent.getLocalTranslation());
            float distanceToCenter = posProjection.subtract(this.orderedPointsList.get(this.nextSpineJoint)).length();
            //chaeck if the agent is outside the path
            if (distanceToCenter > this.pathRadius) {
                //Move to the next spine and inside the path
                Vector3f moveToSpine = this.agent.offset(this.orderedPointsList.get(this.nextSpineJoint)).normalize();
                Vector3f moveToCenter = this.orderedPointsList.get(this.nextSpineJoint).subtract(posProjection).normalize();
                steer = moveToSpine.add(moveToCenter);
            } else {
                //Move through the path
                Vector3f moveThroughPathSteer = exitNormal.normalize();

                Vector3f predictedPos = this.agent.getPredictedPosition();
                Vector3f predictedOffsetFromNextCenter = predictedPos.subtract(this.orderedPointsList.get(this.nextSpineJoint));
                Vector3f projectionIntoSpine = this.orderedPointsList.get(this.nextSpineJoint).add(
                        exitNormal.mult(predictedOffsetFromNextCenter.dot(exitNormal) / exitNormal.lengthSquared()));

                Vector3f predictedOffset = predictedPos.subtract(projectionIntoSpine);
                Vector3f predictedOffsetFromSurface = predictedOffset.subtract(predictedOffset.normalize().mult(this.pathRadius));

                //Path containment
                if (predictedOffset.length() > this.pathRadius) {
                    moveThroughPathSteer = moveThroughPathSteer.add(predictedOffsetFromSurface.mult(cohesionStrength));
                }

                steer = moveThroughPathSteer;

                if (this.nextExit.whichSide(this.agent.getLocalTranslation()) == Side.Positive) {
                    this.nextSpineJoint++;
                }
            }
        } else {
            //The path has ended
            this.active = false;
        }
    }

    return steer;
}
 
Example 13
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 14
Source File: ObstacleAvoidanceBehavior.java    From MonkeyBrains with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
/**
 * @see AbstractSteeringBehavior#calculateSteering()
 */
@Override
protected Vector3f calculateRawSteering() {
    Vector3f nearestObstacleSteerForce = new Vector3f();

    if (this.agent.getVelocity() != null) {
        float agentVel = this.agent.getVelocity().length();
        float minDistanceToCollision = agentVel * timePerFrame * this.minTimeToCollision;

        // test all obstacles for intersection with my forward axis,
        // select the one whose intersection is nearest
        for (GameEntity obstacle : this.obstacles) {
            float distanceFromCenterToCenter = this.agent.distanceRelativeToGameEntity(obstacle);
            if (distanceFromCenterToCenter > this.minDistance) {
                break;
            }

            float distanceFromCenterToObstacleSuperf = distanceFromCenterToCenter - obstacle.getRadius();
            float distance = distanceFromCenterToObstacleSuperf - this.agent.getRadius();

            if (distanceFromCenterToObstacleSuperf < 0) {
                distanceFromCenterToObstacleSuperf = 0;
            }

            if (distance < 0) {
                distance = 0;
            }

            // if it is at least in the radius of the collision cylinder and we are facing the obstacle
            if (this.agent.forwardness(obstacle) > 0
                    && //Are we facing the obstacle ?
                    distance * distance
                    < ((minDistanceToCollision * minDistanceToCollision)
                    + (this.agent.getRadius() * this.agent.getRadius())) //Pythagoras Theorem
                    ) {
                Vector3f velocityNormalized = this.agent.getVelocity().normalize();
                Vector3f distanceVec = this.agent.offset(obstacle).normalize().mult(distanceFromCenterToObstacleSuperf);
                Vector3f projectedVector = velocityNormalized.mult(velocityNormalized.dot(distanceVec));

                Vector3f collisionDistanceOffset = projectedVector.subtract(distanceVec);

                if (collisionDistanceOffset.length() < this.agent.getRadius()) {
                    Vector3f collisionDistanceDirection;

                    if (!collisionDistanceOffset.equals(Vector3f.ZERO)) {
                        collisionDistanceDirection = collisionDistanceOffset.normalize();
                    } else {
                        collisionDistanceDirection = randomVectInPlane(this.agent.getVelocity(), this.agent.getLocalTranslation()).normalize();
                    }

                    Vector3f steerForce = collisionDistanceDirection.mult((this.agent.getRadius() - collisionDistanceOffset.length())
                            / this.agent.getRadius());

                    if (steerForce.length() > nearestObstacleSteerForce.length()) {
                        nearestObstacleSteerForce = steerForce;
                    }
                }
            }
        }
    }
    return nearestObstacleSteerForce;
}
 
Example 15
Source File: DynamicInsetsComponent.java    From Lemur with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
@Override
public void reshape( Vector3f pos, Vector3f size ) {
    Vector3f prefSize = lastPreferredSize;
    if( prefSize == null ) {
    
        // Dynamic insets by its nature is going to be the
        // 'base' component or very close to it.  If we don't have
        // a lastPreferredSize then it means calculatePreferredSize
        // was never called.  This can be the result of our parent
        // already knowing what it's preferred size is.  So if 
        // we are attached we will assume that our parent knows
        // best.  We won't cache the value, though, since it implies
        // that we might be incorrect later.  We'll fetch it every time.
        if( isAttached() ) {
            prefSize = getGuiControl().getPreferredSize(); 
        } else {           
            // There is nothing we can do, so we won't do anything
            return;
        }
    }

    // Otherwise, see what the difference is between our
    // desired size and
    Vector3f delta = size.subtract(prefSize);
    Insets3f insets = getInsets();
    for( int i = 0; i < 3; i++ ) {
        float d = delta.get(i);
        if( d <= 0 ) {
            // We don't go smaller than preferred size so
            // we skip if less than 0 and 0 would be a no-op
            // anyway so we skip then too
            continue;
        }

        float min = insets.min.get(i);
        float max = insets.max.get(i);
        float p = pos.get(i);
        float s = size.get(i);

        if( i == 1 ) {
            // To match regular insets we invert y adjustment
            // so that min is at the top.
            pos.set(i, p - min * d);
        } else {
            pos.set(i, p + min * d);
        }
        
        // Set the size such that min and max are accounted
        // for
        size.set(i, s - (min * d + max * d));
    }
}
 
Example 16
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;
        }
    }
}
 
Example 17
Source File: MoveTool.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@Override
public void draggedPrimary(Vector2f screenCoord, boolean pressed, JmeNode rootNode, DataObject currentDataObject) {
    if (!pressed) {
        setDefaultAxisMarkerColors();
        pickedPlane = null; // mouse released, reset selection
        offset = null;
        if (wasDragging) {
            actionPerformed(new MoveUndo(toolController.getSelectedSpatial(), startLoc, lastLoc));
            wasDragging = false;
        }
        return;
    }
    
    if (toolController.getSelectedSpatial() == null)
        return;
    if (pickedPlane == null) {
        pickedPlane = pickAxisMarker(camera, screenCoord, axisPickType);
        if (pickedPlane == null)
            return;
        startLoc = toolController.getSelectedSpatial().getLocalTranslation().clone();
        
        if (pickedPlane.equals(new Vector3f(1,1,0)))
            plane.setLocalRotation(XY);
        else if (pickedPlane.equals(new Vector3f(1,0,1)))
            plane.setLocalRotation(XZ);
        else if (pickedPlane.equals(new Vector3f(0,1,1)))
            plane.setLocalRotation(YZ);
        plane.setLocalTranslation(startLoc);
    }
    
    Vector3f planeHit = pickWorldLocation(camera, screenCoord, plane);
    if (planeHit == null)
        return;

    if (offset == null)
        offset = planeHit.subtract(startLoc); // get the offset when we start so it doesn't jump

    Vector3f newPos = planeHit.subtract(offset);
    lastLoc = newPos;
    toolController.getSelectedSpatial().setLocalTranslation(newPos);
    updateToolsTransformation();
    
    wasDragging = true;
}
 
Example 18
Source File: TerrainGrid.java    From MikuMikuStudio with BSD 2-Clause "Simplified" License 3 votes vote down vote up
/**
 * Get the location in cell-coordinates of the specified location.
 * Cell coordinates are integer corrdinates, usually with y=0, each 
 * representing a cell in the world.
 * For example, moving right in the +X direction:
 * (0,0,0) (1,0,0) (2,0,0), (3,0,0)
 * and then down the -Z direction:
 * (3,0,-1) (3,0,-2) (3,0,-3)
 */
public Vector3f getCamCell(Vector3f location) {
    Vector3f tile = getTileCell(location);
    Vector3f offsetHalf = new Vector3f(-0.5f, 0, -0.5f);
    Vector3f shifted = tile.subtract(offsetHalf);
    return new Vector3f(FastMath.floor(shifted.x), 0, FastMath.floor(shifted.z));
}
 
Example 19
Source File: TerrainGrid.java    From jmonkeyengine with BSD 3-Clause "New" or "Revised" License 3 votes vote down vote up
/**
 * Get the location in cell-coordinates of the specified location.
 * Cell coordinates are integer corrdinates, usually with y=0, each 
 * representing a cell in the world.
 * For example, moving right in the +X direction:
 * (0,0,0) (1,0,0) (2,0,0), (3,0,0)
 * and then down the -Z direction:
 * (3,0,-1) (3,0,-2) (3,0,-3)
 */
public Vector3f getCamCell(Vector3f location) {
    Vector3f tile = getTileCell(location);
    Vector3f offsetHalf = new Vector3f(-0.5f, 0, -0.5f);
    Vector3f shifted = tile.subtract(offsetHalf);
    return new Vector3f(FastMath.floor(shifted.x), 0, FastMath.floor(shifted.z));
}
 
Example 20
Source File: GameEntity.java    From MonkeyBrains with BSD 3-Clause "New" or "Revised" License 2 votes vote down vote up
/**
 * @param positionVector
 * @return The offset relative to an position vector
 */
public Vector3f offset(Vector3f positionVector) {
    return positionVector.subtract(getLocalTranslation());
}