three.js官方案例(animation / skinning / ik)webgl_animation_skinning_ik.html学习记录

目录

1 WebGLCubeRenderTarget

2 TransformControls   

3 CCDIKSolver

4 CCDIKHelper

4 全部脚本


1 WebGLCubeRenderTarget

球体亮

//WebGLCubeRenderTarget(size : Number, options : Object)
//size - the size, in pixels. Default is 1.
//options - (可选)一个保存着自动生成的目标纹理的纹理参数以及表示是否使用深度缓存/模板缓存的布尔值的对象。const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 1024 );mirrorSphereCamera = new THREE.CubeCamera( 0.05, 50, cubeRenderTarget );//创建6个渲染到WebGLCubeRenderTarget的摄像机scene.add( mirrorSphereCamera );const mirrorSphereMaterial = new THREE.MeshBasicMaterial( { envMap: cubeRenderTarget.texture } );OOI.sphere.material = mirrorSphereMaterial;//球体材质设置

2 TransformControls   

可以用来拖拽模型

transformControls = new TransformControls( camera, renderer.domElement );//camera是渲染场景的相机 renderer.domElement是控制器附加到的html元素transformControls.size = 0.75;//以像素为单位的变换控制器的大小transformControls.showX = false;//指示是否显示沿 X轴的控制手柄。transformControls.space = 'world';//指定变换空间(‘local’ 或 ‘world’),其中应用变换transformControls.attach( OOI.target_hand_l );//将控制器附加到指定的对象以进行操作scene.add( transformControls );

3 CCDIKSolver

        CCDIKSolver 用 CCD 算法解决逆运动学问题。 CCDIKSolver 设计用于与 SkinnedMesh 配合使用,但也可与 MMDLoader 或 GLTFLoader 配合使用。

构造函数

CCDIKSolver( mesh : SkinnedMesh, iks : Array )

mesh — SkinnedMesh 用于 CCDIKSolver 解决 IK 问题
iks — 指定 IK 参数的对象 Object 数组。target、effector 和 link-index 是 .sculptor.bones 中的索引整数。骨骼关系从父级到子级的顺序应为“links[ n ]、 links[ n - 1 ]、...、 links[ 0 ]、effector”。

  • target — 目标骨骼
  • effector — 效应器骨
  • links — 指定链接骨骼的对象Object 数组
    • index — 链接骨骼
    • limitation — (可选)旋转轴。默认值 undefined
    • rotationMin — (可选)旋转最小限制。默认值 undefined
    • rotationMax — (可选)旋转最大限制。默认值 undefined
    • enabled — (可选)默认值为 true。
  • iteration — (可选)计算的迭代次数。越小速度越快,但精度较差。默认值为 1。
  • minAngle — (可选)一步中的最小旋转角度。默认值 undefined
  • maxAngle — (可选)一步中的最大旋转角度。默认值 undefined

4 CCDIKHelper

IKSolver = new CCDIKSolver( OOI.kira, iks );//动画const ccdikhelper = new CCDIKHelper( OOI.kira, iks, 0.01 );//辅助scene.add( ccdikhelper );

4 全部脚本

<!DOCTYPE html>
<html lang="en"><head><title>three.js webgl - animation - skinning - ik</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"><meta name="author" content="Antoine BERNIER (abernier)" /><link type="text/css" rel="stylesheet" href="main.css"><style>body {color:white;}#info a {color:#4d6675;}</style></head><body><div id="info"><a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - webgl - inverse kinematics<br />Character model by <a href="https://assetstore.unity.com/packages/3d/characters/humanoids/humans/kira-lowpoly-character-100303" target="_blank" rel="noopener">Aki</a>, furnitures from <a href="https://poly.pizza" target="_blank" rel="noopener">poly.pizza</a>, scene by <a href="https://abernier.name/three.js/examples/webgl_esher.html" target="_blank" rel="noopener">abernier</a>. CC0.</div><script type="importmap">{"imports": {"three": "../build/three.module.js","three/addons/": "./jsm/"}}</script><script type="module">import * as THREE from 'three';import { OrbitControls } from 'three/addons/controls/OrbitControls.js';//控制器引入import { TransformControls } from 'three/addons/controls/TransformControls.js';//转换控件 控制器  交互操作import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';//GLTF模型加载器import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';//一个用于加载经过Draco压缩的图形库  和GLTFLoader 一同出现import { CCDIKSolver, CCDIKHelper } from './jsm/animation/CCDIKSolver.js';//动画相关库  一种基于 CCD Algorithm 的 IK 解算器import Stats from 'three/addons/libs/stats.module.js';//性能检测import { GUI } from 'three/addons/libs/lil-gui.module.min.js';//UIlet scene, camera, renderer, orbitControls, transformControls,transformControls2 ;let mirrorSphereCamera;const OOI = {};let IKSolver;let stats, gui, conf;const v0 = new THREE.Vector3();init().then( animate );//先后顺序async function init() {conf = {followSphere: false,turnHead: true,ik_solver: true,update: updateIK};//定义一些用到的字段//场景scene = new THREE.Scene();scene.fog = new THREE.FogExp2( 0xffffff, .17 );scene.background = new THREE.Color( 0xffffff );//相机camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 0.001, 5000 );camera.position.set( 0.9728517749133652, 1.1044765132727201, 0.7316689528482836 );camera.lookAt( scene.position );//灯光const ambientLight = new THREE.AmbientLight( 0xffffff, 8 ); // soft white lightscene.add( ambientLight );//渲染器renderer = new THREE.WebGLRenderer( { antialias: true, logarithmicDepthBuffer: true } );renderer.setPixelRatio( window.devicePixelRatio );renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );//性能检测stats = new Stats();document.body.appendChild( stats.dom );//控制器orbitControls = new OrbitControls( camera, renderer.domElement );orbitControls.minDistance = 0.2;orbitControls.maxDistance = 1.5;orbitControls.enableDamping = true;//orbitControls.addEventListener( 'change', animate );//开始下载模型const dracoLoader = new DRACOLoader();dracoLoader.setDecoderPath( 'jsm/libs/draco/' );const gltfLoader = new GLTFLoader();gltfLoader.setDRACOLoader( dracoLoader );			const gltf = await gltfLoader.loadAsync( 'models/gltf/kira.glb' );//异常加载			console.log(OOI);console.log(gltf.scene);gltf.scene.traverse( n => {if ( n.name === 'head' ) OOI.head = n;//头if ( n.name === 'lowerarm_l' ) OOI.lowerarm_l = n;if ( n.name === 'Upperarm_l' ) OOI.Upperarm_l = n;if ( n.name === 'hand_l' ) OOI.hand_l = n;if ( n.name === 'target_hand_l' ) OOI.target_hand_l = n;if ( n.name === 'boule' ) OOI.sphere = n;//球if ( n.name === 'Kira_Shirt_left' ) OOI.kira = n;} );scene.add( gltf.scene );//orbitControls.target.copy( new THREE.Vector3(1.7835944890975952,1.023118257522583,-0.25029030442237854) );orbitControls.target.copy( OOI.sphere.position ); // orbit controls lookAt the sphere 看向球OOI.hand_l.attach( OOI.sphere );//.attach ( object : Object3D ) : 将object作为子级来添加到该对象中,同时保持该object的世界变换。// // mirror sphere cube-camera//WebGLCubeRenderTarget(size : Number, options : Object)
//size - the size, in pixels. Default is 1.
//options - (可选)一个保存着自动生成的目标纹理的纹理参数以及表示是否使用深度缓存/模板缓存的布尔值的对象。const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 1024 );mirrorSphereCamera = new THREE.CubeCamera( 0.05, 50, cubeRenderTarget );//创建6个渲染到WebGLCubeRenderTarget的摄像机scene.add( mirrorSphereCamera );const mirrorSphereMaterial = new THREE.MeshBasicMaterial( { envMap: cubeRenderTarget.texture } );OOI.sphere.material = mirrorSphereMaterial;//球体材质设置transformControls = new TransformControls( camera, renderer.domElement );//camera是渲染场景的相机 renderer.domElement是控制器附加到的html元素transformControls.size = 0.75;//以像素为单位的变换控制器的大小transformControls.showX = false;//指示是否显示沿 X轴的控制手柄。transformControls.space = 'world';//指定变换空间(‘local’ 或 ‘world’),其中应用变换transformControls.attach( OOI.target_hand_l );//将控制器附加到指定的对象以进行操作scene.add( transformControls );// disable orbitControls while using transformControlstransformControls.addEventListener( 'mouseDown', () => orbitControls.enabled = false );//鼠标按下时 控制器失效transformControls.addEventListener( 'mouseUp', () => orbitControls.enabled = true );OOI.kira.add( OOI.kira.skeleton.bones[ 0 ] );//骨骼const iks = [{target: 22, // "target_hand_l"effector: 6, // "hand_l"links: [{index: 5, // "lowerarm_l"rotationMin: new THREE.Vector3( 1.2, - 1.8, - .4 ),rotationMax: new THREE.Vector3( 1.7, - 1.1, .3 )},{index: 4, // "Upperarm_l"rotationMin: new THREE.Vector3( 0.1, - 0.7, - 1.8 ),rotationMax: new THREE.Vector3( 1.1, 0, - 1.4 )},],}];IKSolver = new CCDIKSolver( OOI.kira, iks );//动画const ccdikhelper = new CCDIKHelper( OOI.kira, iks, 0.01 );//辅助scene.add( ccdikhelper );//UI部分gui = new GUI();gui.add( conf, 'followSphere' ).name( 'follow sphere' );//跟随球体gui.add( conf, 'turnHead' ).name( 'turn head' );//转动头gui.add( conf, 'ik_solver' ).name( 'IK auto update' );//自动更新gui.add( conf, 'update' ).name( 'IK manual update()' );//gui.open();window.addEventListener( 'resize', onWindowResize, false );const geometry = new THREE.BoxGeometry();const spherMaterial = new THREE.MeshLambertMaterial({ color: 'red' });const mesh=new THREE.Mesh(geometry,spherMaterial);mesh.position.set(0,1,-1);scene.add(mesh);transformControls2 = new TransformControls( camera, renderer.domElement );//camera是渲染场景的相机 renderer.domElement是控制器附加到的html元素transformControls2.size = 0.75;//以像素为单位的变换控制器的大小//transformControls2.showX = false;//指示是否显示沿 X轴的控制手柄。transformControls2.space = 'world';//指定变换空间(‘local’ 或 ‘world’),其中应用变换transformControls2.attach( mesh );//将控制器附加到指定的对象以进行操作scene.add( transformControls2 );						transformControls2.addEventListener('dragging-changed',function(event){orbitControls.enabled=!event.value;});}function animate( ) {if ( OOI.sphere && mirrorSphereCamera ) {OOI.sphere.visible = false;OOI.sphere.getWorldPosition( mirrorSphereCamera.position );mirrorSphereCamera.update( renderer, scene );OOI.sphere.visible = true;}if ( OOI.sphere && conf.followSphere ) {// orbitControls follows the sphereOOI.sphere.getWorldPosition( v0 );orbitControls.target.lerp( v0, 0.1 );}if ( OOI.head && OOI.sphere && conf.turnHead ) {// turn headOOI.sphere.getWorldPosition( v0 );OOI.head.lookAt( v0 );OOI.head.rotation.set( OOI.head.rotation.x, OOI.head.rotation.y + Math.PI, OOI.head.rotation.z );}if ( conf.ik_solver ) {updateIK();}orbitControls.update();renderer.render( scene, camera );stats.update(); // fps statsrequestAnimationFrame( animate );}function updateIK() {
//IKSolver.update () : this  通过求解 CCD 算法更新 IK 骨骼四元数if ( IKSolver ) IKSolver.update();scene.traverse( function ( object ) {//计算边界球体,更新 .boundingSphere 属性。
//默认情况下不计算边界球体。它们需要显式计算,否则它们是 . 如果 SkinnedMesh 的实例是动画的,则应按帧调用此方法以计算正确的边界球体。nullif ( object.isSkinnedMesh ) object.computeBoundingSphere();} );}function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();renderer.setSize( window.innerWidth, window.innerHeight );}</script></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/45870.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件设计之Java入门视频(15)

软件设计之Java入门视频(15) 视频教程来自B站尚硅谷&#xff1a; 尚硅谷Java入门视频教程&#xff0c;宋红康java基础视频 相关文件资料&#xff08;百度网盘&#xff09; 提取密码&#xff1a;8op3 idea 下载可以关注 软件管家 公众号 学习内容&#xff1a; 该视频共分为1-7…

Linux桌面溯源

X窗口系统(X Window System) Linux起源于X窗口系统&#xff08;X Window System&#xff09;&#xff0c;亦即常说的X11&#xff0c;因其版本止于11之故。 X窗口系统&#xff08;X Window System&#xff0c;也常称为X11或X&#xff09;是一种以位图方式显示的软件窗口系统。…

zabbix 7.0 SNMP Hex数据预处理新功能

一、简介 zabbix7.0新特性是监控项新增支持SNMP Hex数据预处理。其中内置了对snmp请求结果Hex转换处理&#xff0c;不再需要使用繁琐的方式&#xff0c;如javascript脚本、替换、修整等方式处理将监控项取值做可视化处理&#xff0c;大福提升SNMP采集获取到Hex数据的处理效率。…

浅析 VO、DTO、DO、PO 的概念

文章目录 I 浅析 VO、DTO、DO、PO1.1 概念1.2 模型1.3 VO与DTO的区别I 浅析 VO、DTO、DO、PO 1.1 概念 VO(View Object) 视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。DTO(Data Transfer Object): 数据传输对象,这个概念来源于J2EE的设…

【C++】优先级队列(底层代码解释)

一. 定义 优先级队列是一个容器适配器&#xff0c;他可以根据不同的需求采用不同的容器来实现这个数据结构&#xff0c;优先级队列采用了堆的数据结构&#xff0c;默认使用vector作为容器&#xff0c;且采用大堆的结构进行存储数据。 &#xff08;1&#xff09;在第一个构造函数…

Qt之元对象系统

Qt的元对象系统提供了信号和槽机制&#xff08;用于对象间的通信&#xff09;、运行时类型信息和动态属性系统。 元对象系统基于三个要素&#xff1a; 1、QObject类为那些可以利用元对象系统的对象提供了一个基类。 2、在类声明中使用Q_OBJECT宏用于启用元对象特性&#xff0c…

项目收获总结--本地缓存方案选型及使用缓存的坑

本地缓存方案选型及使用缓存的坑 一、摘要二、本地缓存三、本地缓存实现方案3.1 自己编程实现一个缓存3.2 基于 Guava Cache 实现本地缓存3.3 基于 Caffeine 实现本地缓存3.4 基于 Encache 实现本地缓存3.5 小结 四、使用缓存的坑4.1 缓存穿透4.2 缓存击穿4.3 缓存雪崩4.4 数据…

如何管理好【管理层】?

如何管理好管理层? 现在流行“找客户痛点,不如找领导G点” 管理好管理层比管理好员工更重要,不要让管理层成为传话筒。你是抱着很大期望提供优厚的待遇聘用管理层,对于所有人来说,你需要一个这样的职位,对于他需要一分工作而已。出色的管理层就像出色的员工一样非常难寻…

leetcode日记(38)字母异位词分组

最开始的想法是创建vector<vector<string>> result&#xff0c;然后遍历strs中字符串&#xff0c;遍历result中vector&#xff0c;比较vector中第一个string和strs中string&#xff0c;若为字母异位词&#xff0c;则加入vector&#xff0c;若无&#xff0c;则创建新…

新手-前端生态

文章目录 新手的前端生态一、概念的理解1、脚手架2、组件 二、基础知识1、HTML2、css3、JavaScript 三、主流框架vue3框架 四、 工具&#xff08;特定框架&#xff09;1、uinapp 五、组件库&#xff08;&#xff09;1、uView如何在哪项目中导入uView 六、应用&#xff08;各种应…

Vulnhub靶场 | DC系列 - DC2

目录 环境搭建渗透测试 环境搭建 靶机镜像下载地址&#xff1a;https://vulnhub.com/entry/dc-2,311/需要将靶机和 kali 攻击机放在同一个局域网里&#xff1b;本实验kali 的 IP 地址&#xff1a;192.168.10.146。 渗透测试 使用 nmap 扫描 192.168.10.0/24 网段存活主机 …

2024年辽宁省数学建模竞赛C题超详细解题思路+问题一案代码分享

本文将为大家带来2024年C题超详细解题思路&#xff0c;本次竞赛6000人参加&#xff0c;共计2400队伍。C题作为本次竞赛中最简单的一道题目&#xff0c;意味着选题人数也将是最多的。因此&#xff0c;本文将对C题的解题思路以及将要面对的问题&#xff0c;进行详细的说明。希望我…

基于深度学习的组织病理学图像IDC检测方法

乳腺癌可以通过对浸润性导管性乳腺癌(IDC)和浸润性小叶性乳腺癌(ILC)的内部组织区域进行检查来确诊。因此&#xff0c;早期诊断乳腺组织异常是至关重要的&#xff0c;以减少风险&#xff0c;使快速和有效的治疗。本研究旨在利用所提出的基于深度学习的算法&#xff0c;利用组织…

本地部署 EVE: Unveiling Encoder-Free Vision-Language Models

本地部署 EVE: Unveiling Encoder-Free Vision-Language Models 0. 引言1. 快速开始2. 运行 Demo 0. 引言 EVE (Encoder-free Vision-language model) 是一种创新的多模态 AI 模型&#xff0c;主要特点是去除了传统视觉语言模型中的视觉编码器。 核心创新 架构创新&#xff…

C++的deque(双端队列),priority_queue(优先级队列)

deque deque是一个容器,是双端队列,从功能上来讲,deque是一个vector和list的结合体 顺序表和链表 deque的结构和优缺点 开辟buff小数组,空间不够了,不扩容,而是开辟一个新的小数组 开辟中控数组(指针数组)指向buff小数组 将已存在的数组指针存在中控数组中间,可以使用下标访…

MICS2024|数字病理与人工智能在乳腺癌精准诊疗中的应用

小罗碎碎念 这两天在厦大开会&#xff0c;医学图像相关的学术会议。来之前一直在我自己的交流群里宣传这个会议&#xff0c;因为自己的推文与病理相关的比较多&#xff0c;所以群里的同行也比较关注这个会议病理相关的内容。 讲者简介 Scopus主页&#xff1a;https://www.scop…

旋转电连接器抗干扰性有哪几个方面?

旋转电连接器作为一种精密的电气传输装置&#xff0c;它实现了两个相对旋转部件间的功率和信号传输。通过旋转电连接器可以传输高频的交流电、高电压的交流电、大电流的交流电、弱小的直流小信号等多种电信号&#xff0c;但是由仪器之间的距离有限&#xff0c;在如此短的距离内…

蓝桥杯算法周赛开赛啦

提醒&#xff1a;19:00算法双周赛准时开启&#xff01; 单题“一血”可获得云课定制便携风扇&#xff01; &#x1f9e7;入榜最高200元&#xff01;还可抽20&#xff5e;100元现金 &#x1fad8;每月参加2次算法双周赛&#xff0c;额外发放88个实验豆&#xff01; 参赛链接…

C++:类和对象 I(访问限定符、this指针)

目录 类的定义 类的大小 访问限定符 实例化 this指针 类的定义 class就是类&#xff0c;class是C中的一个关键字 当然类也可以是C语言中的struct&#xff0c;C兼容struct&#xff0c;甚至还有一些升级 定义类的方式 class Date {}; 和C语言的struct一样&#xff0c;c…

企业国产操作系统选型适配实施方案

【摘要】企业在推动国产化进程时&#xff0c;需选择一款主流、稳定且安全的服务器操作系统作为其系统软件。在产品投入实际生产环境前&#xff0c;对上游软硬件的适配情况有深入了解至关重要。本文将重点介绍银河麒麟高级服务器操作系统V10&#xff08;以下简称麒麟V10&#xf…