/** * Compute bounds from an array of points * * @param pts * @param transform * @return */ public static BoundingBox computeBoundForPoints(Vector3f[] pts, Transform transform) { Vector3f min = new Vector3f(Vector3f.POSITIVE_INFINITY); Vector3f max = new Vector3f(Vector3f.NEGATIVE_INFINITY); Vector3f temp = new Vector3f(); for (int i = 0; i < pts.length; i++) { transform.transformVector(pts[i], temp); min.minLocal(temp); max.maxLocal(temp); } Vector3f center = min.add(max).multLocal(0.5f); Vector3f extent = max.subtract(min).multLocal(0.5f); return new BoundingBox(center, extent.x, extent.y, extent.z); }
/** * Compute bounds from an array of points * * @param pts * @param mat * @return */ public static BoundingBox computeBoundForPoints(Vector3f[] pts, Matrix4f mat) { Vector3f min = new Vector3f(Vector3f.POSITIVE_INFINITY); Vector3f max = new Vector3f(Vector3f.NEGATIVE_INFINITY); Vector3f temp = new Vector3f(); for (int i = 0; i < pts.length; i++) { float w = mat.multProj(pts[i], temp); temp.x /= w; temp.y /= w; // Why was this commented out? temp.z /= w; min.minLocal(temp); max.maxLocal(temp); } Vector3f center = min.add(max).multLocal(0.5f); Vector3f extent = max.subtract(min).multLocal(0.5f); // Nehon 08/18/2010 : Added an offset to the extend to avoid banding artifacts when the frustum // are aligned return new BoundingBox(center, extent.x + 2.0f, extent.y + 2.0f, extent.z + 2.5f); }
private static BoneWorldGrid makeBoneWorldGrid( ByteArray3d boneMeshGrid, float worldScale, MyBone bone) { Transform transform = BoneTransformUtils.boneTransform2(bone); // bounding box needed for boneMeshGrid in world grid: float bs = 1.0f; Vector3f c1 = transform.transformVector(new Vector3f(-bs, -bs, -bs), null).multLocal(worldScale); Vector3f c2 = transform.transformVector(new Vector3f(+bs, -bs, -bs), null).multLocal(worldScale); Vector3f c3 = transform.transformVector(new Vector3f(-bs, +bs, -bs), null).multLocal(worldScale); Vector3f c4 = transform.transformVector(new Vector3f(-bs, -bs, +bs), null).multLocal(worldScale); Vector3f c5 = transform.transformVector(new Vector3f(+bs, +bs, -bs), null).multLocal(worldScale); Vector3f c6 = transform.transformVector(new Vector3f(-bs, +bs, +bs), null).multLocal(worldScale); Vector3f c7 = transform.transformVector(new Vector3f(+bs, -bs, +bs), null).multLocal(worldScale); Vector3f c8 = transform.transformVector(new Vector3f(+bs, +bs, +bs), null).multLocal(worldScale); Vector3f cmin = c1.clone(); cmin.minLocal(c2); cmin.minLocal(c3); cmin.minLocal(c4); cmin.minLocal(c5); cmin.minLocal(c6); cmin.minLocal(c7); cmin.minLocal(c8); Vector3f cmax = c1.clone(); cmax.maxLocal(c2); cmax.maxLocal(c3); cmax.maxLocal(c4); cmax.maxLocal(c5); cmax.maxLocal(c6); cmax.maxLocal(c7); cmax.maxLocal(c8); int xsize = (int) FastMath.ceil(cmax.x - cmin.x); int ysize = (int) FastMath.ceil(cmax.y - cmin.y); int zsize = (int) FastMath.ceil(cmax.z - cmin.z); ByteArray3d grid = new ByteArray3d(xsize, ysize, zsize); int w = grid.getWidth(); int h = grid.getHeight(); int d = grid.getDepth(); Vector3f v = new Vector3f(); Vector3f inv = new Vector3f(); Vector3f inv2 = new Vector3f(); // we want to calculate transform: (inv - (-bs)) * (sz / (bs - (-bs))) // se let's precalculate it to (inv + shift) * scale Vector3f scale = new Vector3f(boneMeshGrid.getWidth(), boneMeshGrid.getHeight(), boneMeshGrid.getDepth()) .divideLocal(bs * 2); Vector3f shift = Vector3f.UNIT_XYZ.mult(bs); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { // calculate inverse transform at (x,y,0) and (x,y,1), the rest of the transforms in inner // loop // can be calculated by adding (inv2-inv1) because the transforms are linear v.set(x, y, 0).addLocal(cmin).divideLocal(worldScale); transform.transformInverseVector(v, inv); inv.addLocal(shift).multLocal(scale); v.set(x, y, 1).addLocal(cmin).divideLocal(worldScale); transform.transformInverseVector(v, inv2); inv2.addLocal(shift).multLocal(scale); Vector3f add = inv2.subtractLocal(inv); for (int z = 0; z < d; z++) { inv.addLocal(add); if (inv.x >= 0 && inv.x < boneMeshGrid.getWidth() && inv.y >= 0 && inv.y < boneMeshGrid.getHeight() && inv.z >= 0 && inv.z < boneMeshGrid.getDepth()) { grid.set(x, y, z, boneMeshGrid.get((int) inv.x, (int) inv.y, (int) inv.z)); } } } } // Once the boneMeshGrid has been transformed into world grid, it may suffer from // downsampling and upsampling artifacts (because the sampling is very simple nearest-neighbor). // Blurring the grid helps with both issues (blur=fake antialias). It has the added benefit // that each BoneWorldGrid will have some "smoothing buffer" around the actual shape, so that // the shape blends better with other bones' shapes. blurGrid(grid); BoneWorldGrid bwg2 = new BoneWorldGrid(); bwg2.grid = grid; bwg2.location = new Vector3i(Math.round(cmin.x), Math.round(cmin.y), Math.round(cmin.z)); return bwg2; }