use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class Vertex3d method computeAngleWeightedNormals.
/**
* Compute the normals for all the half-edges indicent on this vertex.
* If none of the half-edges are open or hard, then only one normal
* is computed, which will be shared by all the half-edges.
* Otherwise, extra normals will be computed for the
* sub-regions delimited by open or hard edges.
*
* @param nrms list of normal vectors where the results should be placed
* @param idx starting index into <code>nrms</code> for the result
* @return advanced index
*/
public int computeAngleWeightedNormals(List<Vector3d> nrms, int idx) {
sortHedgesIfNecessary();
HalfEdgeNode node = incidentHedges;
int nrmSize = nrms.size();
while (node != null) {
// XXX chance for index-out-of-bounds here
Vector3d nrm = null;
if (idx < nrmSize) {
nrm = nrms.get(idx++);
nrm.setZero();
} else {
System.err.println("Vertex3d.computeAngleWeightedNormals(...): hack to prevent out of bounds index");
nrm = new Vector3d();
nrms.add(nrm);
++nrmSize;
}
do {
HalfEdge he = node.he;
nrm.angleWeightedCrossAdd(he.tail.pnt, he.head.pnt, he.next.head.pnt);
node = node.next;
} while (node != null && !isNormalBoundary(node.he));
nrm.normalize();
}
return idx;
}
use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class SphereIntersector method bound.
/**
* Bounds the intersection of two spheres
* @param c1 center of sphere 1
* @param r1 radius of sphere 1
* @param c2 center of sphere 2
* @param r2 radius of sphere 2
* @return oriented bounding box
*/
public static OBB bound(Point3d c1, double r1, Point3d c2, double r2) {
Vector3d axis = new Vector3d();
Vector3d xdv = new Vector3d();
double v = intersect(c1, r1, c2, r2, axis, xdv);
if (v <= 0) {
return null;
}
RigidTransform3d trans = new RigidTransform3d();
Vector3d widths = new Vector3d();
if (xdv.y <= r2 - r1) {
// inside r2
trans.setTranslation(c2);
widths.set(r2, r2, r2);
} else if (xdv.y <= r1 - r2) {
// inside r1
trans.setTranslation(c1);
widths.set(r1, r1, r1);
} else {
trans.R.rotateZDirection(axis);
double x = xdv.x;
double d = xdv.y;
double d1 = x;
double d2 = d - x;
// h1 is height of cap 1
// h2 is height of cap 2
double h1 = r1 - d1;
double h2 = r2 - d2;
if (h1 > r1) {
// r1 sticks out
widths.x = r1;
widths.y = r1;
} else if (h2 > r2) {
// r2 sticks out
widths.x = r2;
widths.y = r2;
} else {
// bounded by intersection circle
double r = Math.sqrt(r1 * r1 - x * x);
widths.x = r;
widths.y = r;
}
widths.z = h1 + h2;
// center-z is half-way between (x+h1) and (x-h2)
Vector3d c = new Vector3d(0, 0, x + (h1 - h2) / 2);
c.transform(trans.R);
c.add(c1);
trans.setTranslation(c);
}
return new OBB(widths, trans);
}
use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class GLViewer method setEyeToWorld.
/**
* Sets the eyeToWorld transform for this viewer, using the canonical
* parameters used by the GL <code>lookat</code> method.
*
* @param eye
* position of the eye, in world coordinates
* @param center
* point that the eye is looking at, in world coordinates
* @param up
* up direction, in world coordinates
*/
public void setEyeToWorld(Point3d eye, Point3d center, Vector3d up) {
Vector3d zaxis = new Vector3d();
Vector3d yaxis = new Vector3d();
Vector3d xaxis = new Vector3d();
zaxis.sub(eye, center);
double n = zaxis.norm();
if (n > 1e-12) {
zaxis.scale(1.0 / n);
} else {
RotationMatrix3d R = new RotationMatrix3d();
R.rotateZDirection(up);
R.getColumn(0, zaxis);
R.getColumn(1, xaxis);
R.getColumn(2, yaxis);
}
xaxis.cross(up, zaxis);
n = xaxis.norm();
if (n > 1e-6) {
xaxis.scale(1.0 / n);
yaxis.cross(zaxis, xaxis);
yaxis.normalize();
} else {
RotationMatrix3d R = new RotationMatrix3d();
R.rotateZDirection(zaxis);
R.getColumn(1, yaxis);
R.getColumn(0, xaxis);
}
synchronized (viewMatrix) {
viewMatrix.set(new double[] { xaxis.x, xaxis.y, xaxis.z, -xaxis.dot(eye), yaxis.x, yaxis.y, yaxis.z, -yaxis.dot(eye), zaxis.x, zaxis.y, zaxis.z, -zaxis.dot(eye) });
}
// XXX
if (Math.abs(viewMatrix.getOffset().norm()) < 1e-5) {
// System.err.println ("bang"); Thread.dumpStack();
}
invalidateViewMatrix();
}
use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class GLViewer method zoom.
/**
* Zoom in or out by a specified scale factor. A factor larger than one zooms
* out, while a factor less than one zooms in. In orthographic projection,
* zoom is accomplished changing the frustum size. In perspective projection,
* it is accomplished by moving the eye position along the z axis of the eye
* frame.
*
* @param s
* scale factor
*/
public void zoom(double s) {
if (myFrustum.orthographic) {
myFrustum.fieldHeight *= s;
myFrustum.top *= s;
myFrustum.bottom *= s;
myFrustum.left *= s;
myFrustum.right *= s;
// update projection matrix
computeProjectionMatrix();
} else {
Vector3d reye = new Vector3d();
Point3d eye = getEye();
synchronized (viewMatrix) {
reye.sub(eye, myViewState.myCenter);
reye.transform(viewMatrix);
reye.x = reye.y = 0;
reye.inverseTransform(viewMatrix);
}
eye.scaledAdd(s - 1, reye);
setEyeToWorld(eye, myViewState.myCenter, getActualUpVector());
}
repaint();
}
use of maspack.matrix.Vector3d in project artisynth_core by artisynth.
the class GLViewer method translate.
/**
* Translate the eye position with respect to the x-y plane of the eye frame.
* The center point is translated by the same amount.
*
* @param delx
* x translation amount
* @param dely
* y translation amount
*/
protected void translate(double delx, double dely) {
Vector3d xCam = new Vector3d(), yCam = new Vector3d();
synchronized (viewMatrix) {
viewMatrix.R.getRow(0, xCam);
viewMatrix.R.getRow(1, yCam);
}
Vector3d offset = new Vector3d();
offset.scale(-delx, xCam);
offset.scaledAdd(-dely, yCam, offset);
myViewState.myCenter.add(offset);
Point3d eye = getEye();
eye.add(offset);
setEyeToWorld(eye, myViewState.myCenter, getActualUpVector());
repaint();
}
Aggregations