Skip to content
Snippets Groups Projects
Commit 4091d9d8 authored by Alexander Rose's avatar Alexander Rose
Browse files

added transform methods to Box3D and Sphere3D

parent 8bbe5c94
No related branches found
No related tags found
No related merge requests found
......@@ -2,9 +2,10 @@
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Vec3 } from '../../linear-algebra'
import { Vec3, Mat4 } from '../../linear-algebra'
import { PositionData } from '../common'
import { OrderedSet } from 'mol-data/int';
......@@ -12,10 +13,11 @@ interface Box3D { min: Vec3, max: Vec3 }
namespace Box3D {
export function create(min: Vec3, max: Vec3): Box3D { return { min, max }; }
export function empty(): Box3D { return { min: Vec3.zero(), max: Vec3.zero() }; }
export function computeBounding(data: PositionData): Box3D {
const min = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
const max = [-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE];
const min = Vec3.create(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
const max = Vec3.create(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
const { x, y, z, indices } = data;
for (let t = 0, _t = OrderedSet.size(indices); t < _t; t++) {
......@@ -27,18 +29,49 @@ namespace Box3D {
max[1] = Math.max(y[i], max[1]);
max[2] = Math.max(z[i], max[2]);
}
return { min: Vec3.create(min[0], min[1], min[2]), max: Vec3.create(max[0], max[1], max[2]) }
return { min, max }
}
export function size(box: Box3D) {
return Vec3.sub(Vec3.zero(), box.max, box.min);
/** Get size of the box */
export function size(size: Vec3, box: Box3D): Vec3 {
return Vec3.sub(size, box.max, box.min);
}
export function expand(box: Box3D, delta: Vec3): Box3D {
return {
min: Vec3.sub(Vec3.zero(), box.min, delta),
max: Vec3.add(Vec3.zero(), box.max, delta)
}
export function setEmpty(box: Box3D): Box3D {
Vec3.set(box.min, Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE)
Vec3.set(box.max, -Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE)
return box
}
/** Add point to box */
export function add(box: Box3D, point: Vec3): Box3D {
Vec3.min(box.min, box.min, point)
Vec3.max(box.max, box.max, point)
return box
}
/** Expand box by delta */
export function expand(out: Box3D, box: Box3D, delta: Vec3): Box3D {
Vec3.sub(out.min, box.min, delta)
Vec3.add(out.max, box.max, delta)
return out
}
const tmpTransformV = Vec3.zero()
/** Transform box with a Mat4 */
export function transform(out: Box3D, box: Box3D, m: Mat4): Box3D {
const [ minX, minY, minZ ] = box.min
const [ maxX, maxY, maxZ ] = box.max
setEmpty(out)
add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, minY, minZ), m))
add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, minY, maxZ), m))
add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, maxY, minZ), m))
add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, maxY, maxZ), m))
add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, maxX, minY, minZ), m))
add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, maxX, minY, maxZ), m))
add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, maxX, maxY, minZ), m))
add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, maxX, maxY, maxZ), m))
return out
}
}
......
......@@ -2,18 +2,18 @@
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Vec3 } from '../../linear-algebra'
import { Vec3, Mat4 } from '../../linear-algebra'
import { PositionData } from '../common'
import { OrderedSet } from 'mol-data/int';
interface Sphere3D { center: Vec3, radius: number }
namespace Sphere3D {
export function create(center: Vec3, radius: number): Sphere3D {
return { center, radius };
}
export function create(center: Vec3, radius: number): Sphere3D { return { center, radius }; }
export function zero(): Sphere3D { return { center: Vec3.zero(), radius: 0 }; }
export function computeBounding(data: PositionData): Sphere3D {
const { x, y, z, indices } = data;
......@@ -43,6 +43,13 @@ namespace Sphere3D {
return { center: Vec3.create(cx, cy, cz), radius: Math.sqrt(radiusSq) };
}
/** Transform sphere with a Mat4 */
export function transform(out: Sphere3D, sphere: Sphere3D, m: Mat4): Sphere3D {
Vec3.transformMat4(out.center, sphere.center, m)
out.radius = sphere.radius * Mat4.getMaxScaleOnAxis(m)
return out
}
}
export { Sphere3D }
\ No newline at end of file
......@@ -873,6 +873,13 @@ namespace Mat4 {
return out;
}
export function getMaxScaleOnAxis(m: Mat4) {
const scaleXSq = m[0] * m[0] + m[1] * m[1] + m[2] * m[2]
const scaleYSq = m[4] * m[4] + m[5] * m[5] + m[6] * m[6]
const scaleZSq = m[8] * m[8] + m[9] * m[9] + m[10] * m[10]
return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq))
}
/** Rotation matrix for 90deg around x-axis */
export const rotX90: ReadonlyMat4 = Mat4.fromRotation(Mat4.identity(), degToRad(90), Vec3.create(1, 0, 0))
/** Rotation matrix for 180deg around x-axis */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment