/* * @Description : * @Author : 赵耀圣 * @QQ : 549184003 * @Date : 2021-03-22 17:27:16 * @LastEditTime : 2021-03-23 18:01:49 * @FilePath : \cga.js\src\IKanimation\CCDSolver.ts */ import { clamp } from "../math/Math"; import { Plane } from "../struct/3d/Plane"; import { Quat } from "../math/Quat"; import { v3, Vec3 } from "../math/Vec3"; import { TypedConstraint } from "./constaint/constraint"; import { ISolver } from "./isolver"; import { Skeleton } from "./skeleton"; const _quat = new Quat(); const _plane = new Plane(); /** * @description : * @param {*} * @return {*} * @example : */ export class CCDSolver implements ISolver { constructor() { } updateTarget() { } projectPlane(v: Vec3, normal: Vec3) { return v.clone().projectOnPlaneNormal(normal); } calcAngle(v1: Vec3, v2: Vec3, dir: Vec3) { var vc1 = v1.clone(); var vc2 = v2.clone(); var angle = clamp(vc1.normalize().dot(vc2.normalize()), -1, 1); angle = Math.acos(angle); if (vc1.cross(vc2).dot(dir) < 0) return -angle; return angle; } /** * @description : * @param {Vec3} target 目标点 * @param {Vec3} zeroPos 关节原点 * @param {Vec3} effector 末端效应点 * @return {*} * @example : */ solveTranslate(target: Vec3, zeroPos: Vec3, effector: Vec3) { } /** * @description : * @param {Vec3} target 目标点 * @param {Vec3} zeroPos 关节原点 * @param {Vec3} effector 末端效应点 * @return {*} * @example : */ solveRotation(target: Vec3, zeroPos: Vec3, effector: Vec3, contraints?: TypedConstraint[]) { let dir0 = effector.clone().sub(zeroPos).normalize(); let dir1 = target.clone().sub(zeroPos).normalize(); var rotationAxis = v3().cross(dir0, dir1).normalize(); _plane.setFromPointNormal(zeroPos, rotationAxis); //最近点 const closestDir: Vec3 = this.projectPlane(target, rotationAxis); closestDir.sub(zeroPos); var angle = 0; _quat.setFromUnitVecs(dir0, closestDir); return _quat.clone(); } solveIK(skeleton: Skeleton, target: Vec3) { let i = 0; while (i++ < skeleton.boneNum) { } } solve(bones: any) { // for (var i = bones.Length - 2; i > -1; i--) { // // Slerp if weight is < 0 // //CCD tends to overemphasise the rotations of the bones closer to the target position. Reducing bone weight down the hierarchy will compensate for this effect. // var w = bones[i].weight * IKPositionWeight; // if (w > 0) { // Vec3 toLastBone = bones[bones.Length - 1].transform.position - bones[i].transform.position; // Vec3 toTarget = targetPosition - bones[i].transform.position; // // Get the rotation to direct the last bone to the target // Quat targetRotation = Quat.FromToRotation(toLastBone, toTarget) * bones[i].transform.rotation; // if (w >= 1) bones[i].transform.rotation = targetRotation; // else bones[i].transform.rotation = Quaternion.Lerp(bones[i].transform.rotation, targetRotation, w); // } // } } }