123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- /** @format */
- import {obbIntersect, sphereAABBDistance, sphereOBBDistance} from './AILib'
- import {cBody} from './Body'
- const Vec3 = cc.Vec3
- export enum ShapeType {
- Box = 1,
- Sphere = 2,
- Capsule = 4, //AI TODO
- }
- export abstract class cShape {
- radius = 0
- height = 0
- type = ShapeType.Box
- size = {x: 0, y: 0, z: 0}
- // scale = { x: 1, y: 1, z: 1 };
- center = {x: 0, y: 0, z: 0}
- // halfSize = { x: 0, y: 0, z: 0 };
- aabb: Array<number> = [0, 0, 0, 0, 0, 0]
- constructor(center: cc.Vec3, type: ShapeType) {
- this.type = type
- //this.isDirty = true;
- this.center.x = center.x
- this.center.y = center.y
- this.center.z = center.z
- }
- updateAABB(scale: cc.Vec3, world: cc.Mat3, isIdentity: boolean = true) {
- const size = this.size
- const center = this.center
- const sx = scale.x,
- sy = scale.y,
- sz = scale.z
- const cx = center.x,
- cy = center.y,
- cz = center.z
- let x = size.x * 0.5,
- y = size.y * 0.5,
- z = size.z * 0.5
- const aabb = this.aabb
- if (!isIdentity) {
- const m = world.m
- const uX = m[0] * sx,
- uY = m[1] * sx,
- uZ = m[2] * sx
- const vX = m[3] * sy,
- vY = m[4] * sy,
- vZ = m[5] * sy
- const wX = m[6] * sz,
- wY = m[7] * sz,
- wZ = m[8] * sz
- const cX = uX * cx + vX * cy + wX * cz
- const cY = uY * cx + vY * cy + wY * cz
- const cZ = uZ * cx + vZ * cy + wZ * cz
- const absU = Math.abs(uX) * x + Math.abs(vX) * y + Math.abs(wX) * z
- const absV = Math.abs(uY) * x + Math.abs(vY) * y + Math.abs(wY) * z
- const absW = Math.abs(uZ) * x + Math.abs(vZ) * y + Math.abs(wZ) * z
- ;(aabb[0] = cX - absU), (aabb[1] = cY - absV), (aabb[2] = cZ - absW)
- ;(aabb[3] = cX + absU), (aabb[4] = cY + absV), (aabb[5] = cZ + absW)
- } else {
- x = Math.abs(x * sx)
- y = Math.abs(y * sy)
- z = Math.abs(z * sz)
- aabb[0] = cx * sx - x
- aabb[1] = cy * sy - y
- aabb[2] = cz * sz - z
- aabb[3] = cx * sx + x
- aabb[4] = cy * sy + y
- aabb[5] = cz * sz + z
- }
- return aabb
- }
- }
- export class cBox extends cShape {
- constructor(center: cc.Vec3, size: cc.Vec3) {
- super(center, ShapeType.Box)
- this.size.x = size.x
- this.size.y = size.y
- this.size.z = size.z
- }
- }
- export class cSphere extends cShape {
- constructor(center: cc.Vec3, radius: number) {
- super(center, ShapeType.Sphere)
- this.radius = radius
- this.size.x = radius * 2
- this.size.y = radius * 2
- this.size.z = radius * 2
- }
- }
- //默认y轴竖向
- export class cCapsule extends cShape {
- constructor(center: cc.Vec3, radius: number, height: number) {
- super(center, ShapeType.Capsule)
- this.radius = radius
- this.height = height
- this.size.x = radius * 2
- this.size.y = height * 2
- this.size.z = radius * 2
- }
- }
- const center = new cc.Vec3()
- export const ShapeSupport: Array<(a: cBody, b: cBody) => boolean> = []
- ShapeSupport[ShapeType.Box | ShapeType.Box] = function (a: cBody, b: cBody) {
- //a,b 没有旋转,已进行AABB处理 , 直接返回 true
- if (a.isIdentity && b.isIdentity) return true
- return obbIntersect(a.getCenter(), a.getHalfSize(), a.getRotMat3(), b.getCenter(), b.getHalfSize(), b.getRotMat3())
- }
- ShapeSupport[ShapeType.Box | ShapeType.Sphere] = function (a: cBody, b: cBody) {
- //a没有旋转当AABB处理
- if (a.isIdentity) {
- // 转换到 aabb 坐标系下
- Vec3.subtract(center, b.getCenter(), a.getCenter())
- return sphereAABBDistance(center, b.getRaidus(), a.getHalfSize())
- }
- return sphereOBBDistance(b.getCenter(), b.getRaidus(), a.getCenter(), a.getRotation(), a.getHalfSize())
- }
- ShapeSupport[ShapeType.Sphere | ShapeType.Sphere] = function (a: cBody, b: cBody) {
- let ca = a.getCenter()
- let cb = b.getCenter()
- Vec3.subtract(center, ca, cb)
- let lengthSqr = center.lengthSqr()
- let radii = a.getRaidus() + b.getRaidus()
- return lengthSqr <= radii * radii
- }
- ShapeSupport[ShapeType.Box | ShapeType.Capsule] = function (a: cBody, b: cBody) {
- //AI TODO
- return true
- }
- ShapeSupport[ShapeType.Sphere | ShapeType.Capsule] = function (a: cBody, b: cBody) {
- //AI TODO
- return true
- }
- ShapeSupport[ShapeType.Capsule | ShapeType.Capsule] = function (a: cBody, b: cBody) {
- //AI TODO
- return true
- }
|