use of maspack.matrix.RigidTransform3d in project artisynth_core by artisynth.
the class GL3Viewer method setDefaultMatrices.
private void setDefaultMatrices() {
RigidTransform3d EyeToWorld = new RigidTransform3d(0, -3, 0, 1, 0, 0, Math.PI / 2);
setEyeToWorld(EyeToWorld);
setAxialView(DEFAULT_AXIAL_VIEW);
setModelMatrix(RigidTransform3d.IDENTITY);
}
use of maspack.matrix.RigidTransform3d in project artisynth_core by artisynth.
the class GL3Viewer method drawArrow.
@Override
public void drawArrow(float[] pnt0, float[] pnt1, double rad, boolean capped) {
if (rad < Double.MIN_NORMAL) {
return;
}
int nslices = getSurfaceResolution();
double dx = pnt1[0] - pnt0[0];
double dy = pnt1[1] - pnt0[1];
double dz = pnt1[2] - pnt0[2];
double len = Math.sqrt(dx * dx + dy * dy + dz * dz);
double arrowRad = 3 * rad;
double arrowLen = Math.min(2 * arrowRad, len / 2);
double lenFrac = 1 - arrowLen / len;
float[] coordsMid = new float[] { pnt0[0] + (float) (lenFrac * dx), pnt0[1] + (float) (lenFrac * dy), pnt0[2] + (float) (lenFrac * dz) };
pushModelMatrix();
// compute required rotation
RigidTransform3d lineRot = getLineTransform(pnt0, pnt1);
// scale and translate model matrix
mulModelMatrix(lineRot);
scaleModelMatrix(rad, rad, len - arrowLen);
maybeUpdateState(gl);
updateProgram(gl, RenderingMode.DEFAULT, true, false, false);
GL3Primitive cylinder = myPrimitiveManager.getAcquiredCylinder(gl, nslices, capped);
cylinder.draw(gl);
cylinder.release();
popModelMatrix();
pushModelMatrix();
lineRot.setTranslation(coordsMid[0], coordsMid[1], coordsMid[2]);
mulModelMatrix(lineRot);
scaleModelMatrix(arrowRad, arrowRad, arrowLen);
maybeUpdateState(gl);
GL3Object cone = myPrimitiveManager.getAcquiredCone(gl, nslices, capped);
cone.draw(gl);
cone.release();
// revert matrix transform
popModelMatrix();
}
use of maspack.matrix.RigidTransform3d in project artisynth_core by artisynth.
the class LineSegment method centerInViewer.
public void centerInViewer() {
if (myViewer != null) {
RigidTransform3d X = new RigidTransform3d(XGridToWorld);
X.p.set(myViewer.getCenter());
setGridToWorld(X);
}
}
use of maspack.matrix.RigidTransform3d in project artisynth_core by artisynth.
the class LineSegment method computeFocalPoint.
/**
* Given a plane expressed in eye coordinates, compute a representative focal
* point (in eye coordinates) for this plane, and return the distance
* per-pixal for this focal point. Returning -1 means that the plane is
* invisible.
*
* <p>
* The method works by finding the centroid of the (clipped) polygon
* associated with the grid boundary, as seen in screen coordinates. This
* centroid is the projected back onto the plane.
*/
private double computeFocalPoint(Point3d focus, RigidTransform3d TGW, Renderer renderer) {
RigidTransform3d XGridToEye = new RigidTransform3d();
RigidTransform3d TWorldToEye = renderer.getViewMatrix();
XGridToEye.mul(TWorldToEye, TGW);
if (focus == null) {
focus = new Point3d();
}
if (renderer.isOrthogonal()) {
Plane plane = new Plane();
plane.set(XGridToEye);
computeFocalPoint(focus, plane, 0, 0, 1);
return renderer.getViewPlaneWidth() / renderer.getScreenWidth();
}
double near = renderer.getViewPlaneDistance();
double far = renderer.getFarPlaneDistance();
double vw = renderer.getViewPlaneWidth();
double vh = renderer.getViewPlaneHeight();
// double fov = renderer.getFieldOfViewY();
int height = renderer.getScreenHeight();
double nearDistPerPixel = renderer.getViewPlaneHeight() / height;
GridCentroidComputer newComp = new GridCentroidComputer(myMinSize, near, far);
Point3d cent = new Point3d();
if (!newComp.computeCentroid(cent, XGridToEye, vw, vh)) {
return -1;
}
double zmax = newComp.getZmax();
double zmin = newComp.getZmin();
RotationMatrix3d R = XGridToEye.R;
Plane plane = new Plane(new Vector3d(R.m02, R.m12, R.m22), new Point3d(XGridToEye.p));
double s = plane.intersectLine(focus, cent, Point3d.ZERO);
if (s == Double.POSITIVE_INFINITY) {
focus.scale(-(zmin + zmax) / (2 * near), cent);
}
double zref = -focus.z;
return zref / near * nearDistPerPixel;
}
use of maspack.matrix.RigidTransform3d in project artisynth_core by artisynth.
the class LineSegment method drawGrid.
private void drawGrid(Renderer renderer) {
if (myMinSize == 0) {
return;
}
double distPerPixel = computeFocalPoint(null, XGridToWorld, renderer);
if (distPerPixel == -1) {
// grid is invisible
return;
}
if (myAutoSizedP) {
// start by computing the minor spacing, and then compute the major
// spacing assume 10 cell divisions
GLGridResolution res = updateResolution(distPerPixel);
if (!myResolution.equals(res)) {
if (myUseWorldOrigin) {
// May need to change position to accomodate new resolution.
RigidTransform3d TGWnew = new RigidTransform3d(XGridToWorldTarget);
AlignConstrainer aligner = new AlignConstrainer();
aligner.updatePose(TGWnew, XGridToWorldTarget);
double dpp = computeFocalPoint(null, TGWnew, renderer);
GLGridResolution resx = updateResolution(dpp);
if (resx.equals(res)) {
myResolution.set(res);
setGridToWorld(TGWnew);
} else {
// System.out.println ("cycle detected");
}
// Old code without cycle detection
// myResolution.set (res);
// setGridToWorld (XGridToWorldTarget);
} else {
myResolution.set(res);
}
}
}
double majorSize = myResolution.getMajorCellSize();
int numDivisions = myResolution.getNumDivisions();
// minor cell size
double minorSize;
// number of minor cells on each side of the x and y axes
int halfCellCnt;
minorSize = majorSize / numDivisions;
halfCellCnt = (int) Math.ceil(myMinSize / (2 * minorSize));
if (halfCellCnt == 0) {
halfCellCnt = numDivisions;
} else if (halfCellCnt % numDivisions != 0) {
// increase effective size so grid boundary lies on a major divison
halfCellCnt = numDivisions * (halfCellCnt / numDivisions + 1);
}
// Limit total number of cells that are drawn, in case a sideways view
// produces many subdivisions.
int maxCells = 200;
if (halfCellCnt > maxCells) {
halfCellCnt = maxCells;
}
double halfSize = halfCellCnt * minorSize;
// number of x axis cell divisions
int xcnt = 2 * halfCellCnt + 1;
// maximum x value
double xmax = halfSize;
// minimum x value
double xmin = -xmax;
// number of y axis cell divisions
int ycnt = 2 * halfCellCnt + 1;
// maximum y value
double ymax = halfSize;
// minimum y value
double ymin = -ymax;
// y_axis_i and x_axis_j are the cell division indices associated with
// the grid's x and y axes
double xoff = 0;
double yoff = 0;
if (myUseWorldOrigin) {
Point3d center = new Point3d();
// compute offset so the axes correspond to the real world center
center.inverseTransform(XGridToWorld);
xoff = center.x;
yoff = center.y;
}
int y_axis_i = (int) Math.round((xmax + xoff) / minorSize);
int x_axis_j = (int) Math.round((ymax + yoff) / minorSize);
float[] minorRGB = new float[3];
if (myMinorRGB == null) {
// create a default minor RBG
float s = 0.4f;
for (int i = 0; i < 3; i++) {
minorRGB[i] = s * myMajorRGB[i];
}
if (myViewer != null) {
// blend with background color of viewer
float[] backgroundRGB = myViewer.getBackgroundColor().getRGBColorComponents(null);
for (int i = 0; i < 3; i++) {
minorRGB[i] += (1 - s) * backgroundRGB[i];
}
}
} else {
minorRGB = myMinorRGB;
}
float[] xColor = myXAxisRGB;
float[] yColor = myYAxisRGB;
if (myLockAxesToWorld) {
// x and y axis colors are determined from corresponding world axes
RotationMatrix3d R = XGridToWorld.R;
// world x axis extracted from first column of XGridToWorld.R
xColor = getWorldAxisColor(R.m00, R.m10, R.m20);
// world y axis extracted from second column of XGridToWorld.R
yColor = getWorldAxisColor(R.m01, R.m11, R.m21);
}
// *********************************************************
// Old code that adjusted the intensity of the minor axis lines depending
// on how close we were to changing the grid resolution. This gave a
// smooth transition between different resolutions when
// autosizing. Difficult to get right (and not as necessary) with the
// more complex autosizing algorithm.
//
// // minSpc is the minimum possible value for minorSize. Maximum possible
// // value is 10x this, and the difference is used to determine the minor
// // grid color
// double minSpc = myMinCellPixels * distPerPixel;
//
// if (myAutoSizingP) {
// float s = (float)(minorSize / (10 * minSpc));
// for (int i = 0; i < 3; i++) {
// myMinorRGB[i] = (0.2 + 0.8 * s)*myDivisionRGB[i]
// }
// }
// *********************************************************
// maybe update info
rcacheInfo.update(numDivisions, (float) minorSize, xcnt, ycnt, x_axis_j, y_axis_i, (float) xmin, (float) xmax, (float) ymin, (float) ymax, xColor, yColor, myMajorRGB, minorRGB);
Shading savedShading = renderer.setShading(Shading.NONE);
renderer.setLineWidth(myLineWidth);
renderer.pushModelMatrix();
renderer.mulModelMatrix(XGridToWorld);
renderer.drawLines(rcacheInfo.getRenderObject());
renderer.setDepthOffset(1);
if (myXAxisLabeling != AxisLabeling.OFF || myYAxisLabeling != AxisLabeling.OFF) {
drawAxisLabels(renderer, xcnt, ycnt, majorSize, numDivisions, distPerPixel);
}
renderer.popModelMatrix();
renderer.setLineWidth(1);
renderer.setShading(savedShading);
}
Aggregations