Sometimes, I have to look into the method implementation when I call method.
For example, when I call constructor Ray(Vector3f origin, Vector3f direction).
the parameter instances are stored in Ray instance then it is possible to be accessed and modified elsewhere
using getDirection() / getOrigin() method.
That’s why I constantly insist on using readonly interface.
If it is accepted ( Please~~~ hehe :roll: ) then I’m willing to volunteer to implement it.
Because it will change very very many lines of code, if we don’t do this now then never until jme4.
That’s tragedy for me and jme engine.
If there is the readonly interface, class signature of Ray will be changed like this.
Ray(Vector3f origin, Vector3f direction) is converted to Ray(IVector3f origin, IVector3f direction)
public Vector3f getDirection() → public IVector3f getDirection()
public Vector3f getOrigin() → public IVector3f getOrigin()
Then user confirms that no dangerous situation may occur.
Application’s data will not be changed in the engine core and
engine’s data will not be changed by application.
Comments more than welcome.
Below is the example of ReadOnly Vector3f interface.
[java]
package com.jme3.math;
public interface IVector3f {
/**
 <code>add</code> adds a provided vector to this vector creating a
 resultant vector which is returned. If the provided vector is null, null
 is returned.
*

@param vec

the vector to add to this.<br />

@return the resultant vector.
*/
public Vector3f add(IVector3f vec);
/**
*
 <code>add</code> adds the values of a provided vector storing the
 values in the supplied vector.
*

@param vec

the vector to add to this<br />

@param result

the vector to store the result in<br />

@return result returns the supplied result vector.
*/
public Vector3f add(IVector3f vec, Vector3f result);
/**
*
 <code>add</code> adds the provided values to this vector, creating a
 new vector that is then returned.
*

@param addX

the x value to add.<br />

@param addY

the y value to add.<br />

@param addZ

the z value to add.<br />

@return the result vector.
*/
public Vector3f add(float addX, float addY, float addZ);
/**
*
 <code>scaleAdd</code> multiplies this vector by a scalar then adds the
 given Vector3f.
*

@param scalar

the value to multiply this vector by.<br />

@param add

the value to add<br />
*/
public Vector3f scaleAdd(float scalar, IVector3f add);
/**
*
 <code>scaleAdd</code> multiplies the given vector by a scalar then adds
 the given vector.
*

@param scalar

the value to multiply this vector by.<br />

@param mult

the value to multiply the scalar by<br />

@param add

the value to add<br />
*/
public Vector3f scaleAdd(float scalar, IVector3f mult, IVector3f add);
/**
*
 <code>dot</code> calculates the dot product of this vector with a
 provided vector. If the provided vector is null, 0 is returned.
*

@param vec

the vector to dot with this vector.<br />

@return the resultant dot product of this vector and a given vector.
*/
public float dot(IVector3f vec);
/**
 <code>cross</code> calculates the cross product of this vector with a
 parameter vector v.
*

@param v

the vector to take the cross product of with this.<br />

@return the cross product vector.
*/
public Vector3f cross(IVector3f v);
/**
 <code>cross</code> calculates the cross product of this vector with a
 parameter vector v. The result is stored in <code>result</code>
*

@param v

the vector to take the cross product of with this.<br />

@param result

the vector to store the cross product result.<br />

@return result, after recieving the cross product vector.
*/
public Vector3f cross(IVector3f v,Vector3f result);
/**
 <code>cross</code> calculates the cross product of this vector with a
 parameter vector v. The result is stored in <code>result</code>
*

@param otherX

x component of the vector to take the cross product of with this.<br />

@param otherY

y component of the vector to take the cross product of with this.<br />

@param otherZ

z component of the vector to take the cross product of with this.<br />

@param result

the vector to store the cross product result.<br />

@return result, after recieving the cross product vector.
*/
public Vector3f cross(float otherX, float otherY, float otherZ, Vector3f result);
public Vector3f project(IVector3f other);
/**
 <code>length</code> calculates the magnitude of this vector.
*

@return the length or magnitude of the vector.
*/
public float length();
/**
 <code>lengthSquared</code> calculates the squared value of the
 magnitude of the vector.
*

@return the magnitude squared of the vector.
*/
public float lengthSquared();
/**
 <code>distanceSquared</code> calculates the distance squared between
 this vector and vector v.
*

@param v the second vector to determine the distance squared.

@return the distance squared between the two vectors.
*/
public float distanceSquared(IVector3f v);
/**
 <code>distance</code> calculates the distance between this vector and
 vector v.
*

@param v the second vector to determine the distance.

@return the distance between the two vectors.
*/
public float distance(IVector3f v);
/**
*
 <code>mult</code> multiplies this vector by a scalar. The resultant
 vector is returned.
*

@param scalar

the value to multiply this vector by.<br />

@return the new vector.
*/
public Vector3f mult(float scalar);
/**
*
 <code>mult</code> multiplies this vector by a scalar. The resultant
 vector is supplied as the second parameter and returned.
*

@param scalar the scalar to multiply this vector by.

@param product the product to store the result in.

@return product
*/
public Vector3f mult(float scalar, IVector3f product);
/**
 <code>multLocal</code> multiplies a provided vector to this vector
 internally, and returns a handle to this vector for easy chaining of
 calls. If the provided vector is null, null is returned.
*

@param vec

the vector to mult to this vector.<br />

@return this
*/
public Vector3f mult(IVector3f vec);
/**
 <code>multLocal</code> multiplies a provided vector to this vector
 internally, and returns a handle to this vector for easy chaining of
 calls. If the provided vector is null, null is returned.
*

@param vec

the vector to mult to this vector.<br />

@param store result vector (null to create a new vector)

@return this
*/
public Vector3f mult(IVector3f vec, Vector3f store);
/**
 <code>divide</code> divides the values of this vector by a scalar and
 returns the result. The values of this vector remain untouched.
*

@param scalar

the value to divide this vectors attributes by.<br />

@return the result <code>Vector</code>.
*/
public Vector3f divide(float scalar);
/**
 <code>divide</code> divides the values of this vector by a scalar and
 returns the result. The values of this vector remain untouched.
*

@param scalar

the value to divide this vectors attributes by.<br />

@return the result <code>Vector</code>.
*/
public Vector3f divide(IVector3f scalar);
/**
*
 <code>negate</code> returns the negative of this vector. All values are
 negated and set to a new vector.
*

@return the negated vector.
*/
public Vector3f negate();
/**
*
 <code>subtract</code> subtracts the values of a given vector from those
 of this vector creating a new vector object. If the provided vector is
 null, null is returned.
*

@param vec

the vector to subtract from this vector.<br />

@return the result vector.
*/
public Vector3f subtract(IVector3f vec);
/**
*
 <code>subtract</code>
*

@param vec

the vector to subtract from this<br />

@param result

the vector to store the result in<br />

@return result
*/
public Vector3f subtract(IVector3f vec, Vector3f result);
/**
*
 <code>subtract</code> subtracts the provided values from this vector,
 creating a new vector that is then returned.
*

@param subtractX

the x value to subtract.<br />

@param subtractY

the y value to subtract.<br />

@param subtractZ

the z value to subtract.<br />

@return the result vector.
*/
public Vector3f subtract(float subtractX, float subtractY, float subtractZ);
/**
 <code>normalize</code> returns the unit vector of this vector.
*

@return unit vector of this vector.
*/
public Vector3f normalize();
/**
 <code>angleBetween</code> returns (in radians) the angle between two vectors.
 It is assumed that both this vector and the given vector are unit vectors (iow, normalized).
*

@param otherVector a unit vector to find the angle against

@return the angle in radians.
*/
public float angleBetween(IVector3f otherVector);
/**
 Saves this Vector3f into the given float[] object.
*

@param floats

The float[] to take this Vector3f. If null, a new float[3] is<br />

created.<br />

@return The array, with X, Y, Z float values in that order
*/
public float[] toArray(float[] floats);
public float getX();
public float getY();
public float getZ();
/**

@param index

@return x value if index == 0, y value if index == 1 or z value if index ==

2<br />

@throws IllegalArgumentException

if index is not one of 0, 1, 2.<br />
*/
public float get(int index);
}
[/java]