use of org.rajawali3d.math.vector.Vector3 in project Rajawali by Rajawali.
the class BlockMeshInstance method parseBlock.
public void parseBlock(AWDLittleEndianDataInputStream dis, BlockHeader blockHeader) throws Exception {
// Parse scene block
RajLog.d("Parsing SceneGraph Block at position: " + dis.getPosition());
mSceneGraphBlock = new SceneGraphBlock();
mSceneGraphBlock.readGraphData(blockHeader, dis);
// Block id for geometry
mGeometryID = dis.readUnsignedInt();
// Lookup the geometry or create it if it does not exist.
final BlockHeader geomHeader = blockHeader.blockHeaders.get((short) mGeometryID);
if (geomHeader == null) {
mGeometry = new Object3D(mSceneGraphBlock.lookupName);
} else {
if (geomHeader.parser == null || !(geomHeader.parser instanceof ABaseObjectBlockParser))
throw new ParsingException("Invalid block reference.");
mGeometry = ((ABaseObjectBlockParser) geomHeader.parser).getBaseObject3D().clone(false, true);
mGeometry.setName(mSceneGraphBlock.lookupName);
}
// Apply the materials
final int materialCount = dis.readUnsignedShort();
final Material[] materials = new Material[materialCount];
for (int i = 0; i < materialCount; ++i) {
final long materialID = dis.readUnsignedInt();
if (materialID == 0) {
materials[i] = getDefaultMaterial();
materials[i].addTexture(getDefaultTexture());
} else {
final BlockHeader materialHeader = blockHeader.blockHeaders.get((short) materialID);
if (materialHeader == null || materialHeader.parser == null || !(materialHeader.parser instanceof ATextureBlockParser))
throw new ParsingException("Invalid block reference " + materialID);
materials[i] = ((ATextureBlockParser) materialHeader.parser).getMaterial();
}
}
// mesh instance properties; does it cast a shadow?
AwdProperties properties = dis.readProperties(EXPECTED_PROPS);
mCastsShadow = (boolean) properties.get(PROP_CASTS_SHADOW, true);
final Matrix4 matrix = new Matrix4(mSceneGraphBlock.transformMatrix);
// Set translation
mGeometry.setPosition(matrix.getTranslation());
// Set scale
final Vector3 scale = matrix.getScaling();
mGeometry.setScale(scale.y, scale.x, scale.z);
// Set rotation
mGeometry.setOrientation(new Quaternion().fromMatrix(matrix));
int m = 0;
if (!mGeometry.isContainer())
mGeometry.setMaterial(materials[m++]);
for (int i = 0; i < mGeometry.getNumChildren(); i++) mGeometry.getChildAt(i).setMaterial(materials[Math.min(materials.length - 1, m++)]);
// ignore user properties, skip to end of block
dis.skip(blockHeader.blockEnd - dis.getPosition());
}
use of org.rajawali3d.math.vector.Vector3 in project Rajawali by Rajawali.
the class Object3D method getWorldPosition.
public Vector3 getWorldPosition() {
if (mParentMatrix == null)
return mPosition;
Vector3 worldPos = mPosition.clone();
worldPos.multiply(mParentMatrix);
return worldPos;
}
use of org.rajawali3d.math.vector.Vector3 in project Rajawali by Rajawali.
the class EllipticalOrbitAnimation3D method applyTransformation.
/*
* (non-Javadoc)
* @see rajawali.animation.Animation3D#applyTransformation()
*/
@Override
protected void applyTransformation() {
// Everything here is stored in double precision because single precision floating point causes a major
// overflow. Theory behind math in this method can be looked up easily on Wikipedia.
// Angle in radians (interpolated time from 0 to 1 results in radian angle 0 to 2PI)
double angle = (mDirection == OrbitDirection.CLOCKWISE ? -1 : 1) * mAngle * mInterpolatedTime * MathUtil.PRE_PI_DIV_180;
// Calculate the distances of periapsis and apoapsis to the focal point.
double periapsisRadius = mPeriapsis.distanceTo(mFocalPoint);
double apoapsisRadius = periapsisRadius * (1 + mEccentricity) / (1 - mEccentricity);
// Get the apoapsis point which will be needed to calculate the center point of the ellipse.
// NOTE: Discard least significant digits after 8th decimal places to lower the computational error epsilon.
double uAx = (Math.round(mFocalPoint.x * 1e8) - Math.round(mPeriapsis.x * 1e8)) / 1e8;
double uAy = (Math.round(mFocalPoint.y * 1e8) - Math.round(mPeriapsis.y * 1e8)) / 1e8;
double uAz = (Math.round(mFocalPoint.z * 1e8) - Math.round(mPeriapsis.z * 1e8)) / 1e8;
double mod = Math.sqrt(uAx * uAx + uAy * uAy + uAz * uAz);
if (mod != 0 && mod != 1) {
mod = 1 / mod;
uAx *= mod;
uAy *= mod;
uAz *= mod;
}
double apoapsisDir_x = Math.round(uAx * apoapsisRadius * 1e8) / 1e8;
double apoapsisDir_y = Math.round(uAy * apoapsisRadius * 1e8) / 1e8;
double apoapsisDir_z = Math.round(uAz * apoapsisRadius * 1e8) / 1e8;
double apoapsisPos_x = Math.round((apoapsisDir_x + mFocalPoint.x) * 1e8) / 1e8;
double apoapsisPos_y = Math.round((apoapsisDir_y + mFocalPoint.y) * 1e8) / 1e8;
double apoapsisPos_z = Math.round((apoapsisDir_z + mFocalPoint.z) * 1e8) / 1e8;
// Midpoint between apoapsis and periapsis is the center of the ellipse.
double center_x = Math.round(((mPeriapsis.x + apoapsisPos_x) / 2) * 1e8) / 1e8;
double center_y = Math.round(((mPeriapsis.y + apoapsisPos_y) / 2) * 1e8) / 1e8;
double center_z = Math.round(((mPeriapsis.z + apoapsisPos_z) / 2) * 1e8) / 1e8;
// Calculate semiminor axis length.
double b = Math.sqrt(periapsisRadius * apoapsisRadius);
// Direction vector to periapsis from the center point and ascending node from the center point
double semimajorAxis_x = Math.round((mPeriapsis.x - center_x) * 1e8) / 1e8;
double semimajorAxis_y = Math.round((mPeriapsis.y - center_y) * 1e8) / 1e8;
double semimajorAxis_z = Math.round((mPeriapsis.z - center_z) * 1e8) / 1e8;
double unitSemiMajorAxis_x = semimajorAxis_x;
double unitSemiMajorAxis_y = semimajorAxis_y;
double unitSemiMajorAxis_z = semimajorAxis_z;
mod = Math.sqrt(semimajorAxis_x * semimajorAxis_x + semimajorAxis_y * semimajorAxis_y + semimajorAxis_z * semimajorAxis_z);
if (mod != 0 && mod != 1) {
mod = 1 / mod;
unitSemiMajorAxis_x *= mod;
unitSemiMajorAxis_y *= mod;
unitSemiMajorAxis_z *= mod;
}
// Translate normal vector to the center point.
Vector3 unitNormal = mNormal.clone();
unitNormal.normalize();
double uNx = Math.round(unitNormal.x * 1e8) / 1e8;
double uNy = Math.round(unitNormal.y * 1e8) / 1e8;
double uNz = Math.round(unitNormal.z * 1e8) / 1e8;
double normalCenter_x = center_x + uNx;
double normalCenter_y = center_y + uNy;
double normalCenter_z = center_z + uNz;
mod = Math.sqrt(normalCenter_x * normalCenter_x + normalCenter_y * normalCenter_y + normalCenter_z * normalCenter_z);
if (mod != 0 && mod != 1) {
mod = 1 / mod;
normalCenter_x *= mod;
normalCenter_y *= mod;
normalCenter_z *= mod;
}
// We can calculate the semiminor axis from unit vector of cross product of semimajor axis and the normal.
mScratch1.setAll(unitSemiMajorAxis_x, unitSemiMajorAxis_y, unitSemiMajorAxis_z);
mScratch2.setAll(normalCenter_x, normalCenter_y, normalCenter_z);
Vector3 semiminorAxis = mScratch3.crossAndSet(mScratch1, mScratch2);
semiminorAxis.multiply(b);
// Parametric equation for ellipse in 3D space.
double x = center_x + (Math.cos(angle) * semimajorAxis_x) + (Math.sin(angle) * semiminorAxis.x);
double y = center_y + (Math.cos(angle) * semimajorAxis_y) + (Math.sin(angle) * semiminorAxis.y);
double z = center_z + (Math.cos(angle) * semimajorAxis_z) + (Math.sin(angle) * semiminorAxis.z);
mTransformable3D.setPosition(x, y, z);
}
use of org.rajawali3d.math.vector.Vector3 in project Rajawali by Rajawali.
the class SkeletalAnimationObject3D method setShaderParams.
public void setShaderParams(Camera camera) {
if (!mIsPlaying)
return;
mBoneMatrices.clear();
mBoneMatrices.position(0);
long currentTime = SystemClock.uptimeMillis();
SkeletalAnimationFrame currentFrame = (SkeletalAnimationFrame) mSequence.getFrame(mCurrentFrameIndex);
SkeletalAnimationFrame nextFrame = (SkeletalAnimationFrame) mSequence.getFrame((mCurrentFrameIndex + 1) % mSequence.getNumFrames());
mInterpolation += mFps * (currentTime - mStartTime) / 1000.0;
boolean isTransitioning = mNextSequence != null;
double transitionInterpolation = 0;
if (isTransitioning)
transitionInterpolation = mTransitionInterpolator.getInterpolation((float) ((currentTime - mTransitionStartTime) / mTransitionDuration));
for (int i = 0; i < mJoints.length; ++i) {
SkeletonJoint joint = getJoint(i);
SkeletonJoint fromJoint = currentFrame.getSkeleton().getJoint(i);
SkeletonJoint toJoint = nextFrame.getSkeleton().getJoint(i);
joint.setParentIndex(fromJoint.getParentIndex());
joint.getPosition().lerpAndSet(fromJoint.getPosition(), toJoint.getPosition(), mInterpolation);
joint.getOrientation().slerp(fromJoint.getOrientation(), toJoint.getOrientation(), mInterpolation);
if (isTransitioning) {
SkeletalAnimationFrame currentTransFrame = mNextSequence.getFrame(mCurrentTransitionFrameIndex % mNextSequence.getNumFrames());
SkeletalAnimationFrame nextTransFrame = mNextSequence.getFrame((mCurrentTransitionFrameIndex + 1) % mNextSequence.getNumFrames());
fromJoint = currentTransFrame.getSkeleton().getJoint(i);
toJoint = nextTransFrame.getSkeleton().getJoint(i);
mTmpJoint1.getPosition().lerpAndSet(fromJoint.getPosition(), toJoint.getPosition(), mInterpolation);
mTmpJoint1.getOrientation().slerp(fromJoint.getOrientation(), toJoint.getOrientation(), mInterpolation);
// blend the two animations
mTmpJoint2.getPosition().lerpAndSet(joint.getPosition(), mTmpJoint1.getPosition(), transitionInterpolation);
mTmpJoint2.getOrientation().slerp(joint.getOrientation(), mTmpJoint1.getOrientation(), transitionInterpolation);
joint.getPosition().setAll(mTmpJoint2.getPosition());
joint.getOrientation().setAll(mTmpJoint2.getOrientation());
}
Matrix.setIdentityM(mBoneTranslation, 0);
Matrix.setIdentityM(mBoneRotation, 0);
Matrix.setIdentityM(mBoneMatrix, 0);
Matrix.setIdentityM(mResultMatrix, 0);
Vector3 jointPos = joint.getPosition();
Matrix.translateM(mBoneTranslation, 0, jointPos.x, jointPos.y, jointPos.z);
joint.getOrientation().toRotationMatrix(mBoneRotation);
Matrix.multiplyMM(mBoneMatrix, 0, mBoneTranslation, 0, mBoneRotation, 0);
Matrix.multiplyMM(mResultMatrix, 0, mBoneMatrix, 0, mInverseBindPoseMatrix[i], 0);
joint.setMatrix(mResultMatrix);
int index = 16 * i;
for (int j = 0; j < 16; j++) {
uBoneMatrix[index + j] = mResultMatrix[j];
mBoneMatrices.put(mResultMatrix[j]);
}
}
if (isTransitioning && transitionInterpolation >= .99f) {
isTransitioning = false;
mCurrentFrameIndex = mCurrentTransitionFrameIndex;
mSequence = mNextSequence;
mNextSequence = null;
}
mGeometry.changeBufferData(mBoneMatricesBufferInfo, mBoneMatrices, 0);
if (mInterpolation >= 1) {
mInterpolation = 0;
mCurrentFrameIndex++;
if (mCurrentFrameIndex >= mSequence.getNumFrames())
mCurrentFrameIndex = 0;
if (isTransitioning) {
mCurrentTransitionFrameIndex++;
if (mCurrentTransitionFrameIndex >= mNextSequence.getNumFrames())
mCurrentTransitionFrameIndex = 0;
}
}
mStartTime = currentTime;
}
use of org.rajawali3d.math.vector.Vector3 in project Rajawali by Rajawali.
the class BoundingBox method transform.
public void transform(final Matrix4 matrix) {
mTransformedMin.setAll(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
mTransformedMax.setAll(-Double.MAX_VALUE, -Double.MAX_VALUE, -Double.MAX_VALUE);
for (mI = 0; mI < 8; ++mI) {
Vector3 o = mPoints[mI];
Vector3 d = mTmp[mI];
d.setAll(o);
d.multiply(matrix);
if (d.x < mTransformedMin.x)
mTransformedMin.x = d.x;
if (d.y < mTransformedMin.y)
mTransformedMin.y = d.y;
if (d.z < mTransformedMin.z)
mTransformedMin.z = d.z;
if (d.x > mTransformedMax.x)
mTransformedMax.x = d.x;
if (d.y > mTransformedMax.y)
mTransformedMax.y = d.y;
if (d.z > mTransformedMax.z)
mTransformedMax.z = d.z;
}
}
Aggregations