精华内容
下载资源
问答
  • Three.js动态增删场景模型

    千次阅读 2019-11-06 21:12:38
    需要不断的往场景中添加和移除模型,所以会经常调用到scene,这一件很烦的事,特别当项目很大的时候,你会发现再很多地方乱用scene.add和scene.romove会很容易出错,那有没有什么好方法避免N多次的scene调用的,...

     学习交流欢迎加群:789723098,博主会将一些demo整理共享

    有时候我们在开发一些项目的时候,需要不断的往场景中添加和移除模型,所以会经常调用到scene,这是一件很烦的事,特别是当项目很大的时候,你会发现再很多地方乱用scene.add和scene.romove会很容易出错,那有没有什么好方法避免N多次的scene调用的,当然是有的啦,three.js设计的时候应该也考虑到这个问题了吧,所以就有了THREE.Group这个东西。

    为了解决上述问题,我们可以在一开始实例化一个THREE.Group,然后讲不带任何子对象的group挂载到scene下面,像:

    scene = new THREE.Scene()
    
    group1 = new THREE.Group()
    
    group2 = new THREE.Group()
    
    scene.add(group1, group2)

     从这里开始,你可以根据场景需求,在程序运行的任何阶段,将模型添加到group里面,场景就会自动将模型显示出来,删除的时候亦只需要移除group中的子对象即可:

    group1.remove(...)
    group2.remove(...)
    ......

     这样一来就可以不用频繁调用scene去添加和移除模型。当需要移除某个group时,直接通过scene移除即可:

    scene.remove(group1);
    scene.remove(group2);

     下边时笔者实现的一个demo, 代码如下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    	<style>
    		body {
    			margin: 0;
    			overflow: hidden;
    		}
    	</style>
    </head>
    <body>
    	<script type="module">
    		import * as THREE from './../build/three.module.js';
    		import Stats from './../examples/jsm/libs/stats.module.js';
    		import dat from './../examples/jsm/libs/dat.gui.module.js';
    
    		let container, stats, gui;
    		let renderer, scene, group, camera, ambientLight, directionLight;
    		const w = window.innerWidth, h = window.innerHeight;
    
    		let meshList = [ 'None', 'box', 'sphere', 'plane' ];
    
    		let config = {
    			addMesh: 'None',
    			removeMesh: 'None',
    			removeGroup: () => scene.remove( group ),
    			addGroup: () => scene.add( group )
    		};
    
    		init();
    		render();
    
    		function init() {
    
    			container = document.createElement( 'div' );
    			document.body.append( container );
    
    			scene = new THREE.Scene();
    			scene.background = new THREE.Color( 0x000000 );
    			// scene.fog = new THREE.Fog( 0xffffff, 0x444444 );
    
    			group = new THREE.Group();
    			scene.add( group );
    
    			renderer = new THREE.WebGLRenderer();
    			renderer.setPixelRatio( window.devicePixelRatio );
    			renderer.setSize( w, h );
    			renderer.shadowMap.enabled = false;
    			container.appendChild( renderer.domElement );
    
    			camera = new THREE.PerspectiveCamera( 45, w / h, 1, 1000 );
    			camera.position.set( - 40, 60, 120 );
    			camera.lookAt( new THREE.Vector3() );
    
    			ambientLight = new THREE.AmbientLight( 0x141414 );
    			scene.add( ambientLight );
    
    			directionLight = new THREE.DirectionalLight( 0xffffff );
    			directionLight.position.set( 0, 200, 100 );
    			directionLight.castShadow = true;
    			directionLight.shadow.camera.top = 180;
    			directionLight.shadow.camera.bottom = - 100;
    			directionLight.shadow.camera.left = - 120;
    			directionLight.shadow.camera.right = 120;
    			scene.add( directionLight );
    
    			const box = createMesh( 'box' );
    			box.name = 'box';
    			console.log( box );
    			group.add( box );
    
    			initGui();
    			initStats();
    
    		}
    
    		function createMesh( name ) {
    
    			let mesh;
    			switch ( name ) {
    
    				case 'box':
    					mesh = new THREE.Mesh(
    						new THREE.BoxBufferGeometry( 30, 30, 30 ),
    						new THREE.MeshLambertMaterial( {
    							color: 0x00cc99,
    							side: THREE.DoubleSide
    						} )
    					);
    
    					mesh.position.set( 0, 0, 0 );
    					break;
    
    				case 'sphere':
    					mesh = new THREE.Mesh(
    						new THREE.SphereBufferGeometry( 20, 40, 40 ),
    						new THREE.MeshLambertMaterial( {
    							color: 0x663300,
    							side: THREE.DoubleSide
    
    						} )
    					);
    					mesh.position.set( - 50, 0, 0 );
    					break;
    
    				case 'plane':
    					mesh = new THREE.Mesh(
    						new THREE.PlaneBufferGeometry( 30, 30 ),
    						new THREE.MeshLambertMaterial( {
    							color: 0x3399ff,
    							side: THREE.DoubleSide
    						} )
    					);
    					mesh.position.set( 50, 0, 0 );
    					// mesh.rotation.x = - Math.PI / 2;
    					break;
    
    			}
    
    			return mesh;
    
    		}
    
    		function initGui() {
    
    			gui = new dat.GUI();
    			gui.add( config, 'addMesh', meshList ).onChange( ( e ) => {
    
    				switch ( e ) {
    
    					case 'box':
    						const box = createMesh( 'box' );
    						box.name = 'box';
    						group.add( box );
    						break;
    
    					case 'sphere':
    						const sphere = createMesh( 'sphere' );
    						sphere.name = 'sphere';
    						group.add( sphere );
    						break;
    
    					case 'plane':
    						const plane = createMesh( 'plane' );
    						plane.name = 'plane';
    						group.add( plane );
    						break;
    
    				}
    
    			} );
    			gui.add( config, 'removeMesh', meshList ).onChange( ( e ) => {
    
    				switch ( e ) {
    
    					case 'sphere':
    						removeMeshFromGroup( 'sphere' );
    						break;
    
    					case 'box':
    						removeMeshFromGroup( 'box' );
    						break;
    
    					case 'plane':
    						removeMeshFromGroup( 'plane' );
    						break;
    
    				}
    
    			} );
    			gui.add( config, 'removeGroup' );
    			gui.add( config, 'addGroup' );
    
    		}
    
    		function initStats() {
    
    			stats = new Stats();
    			container.appendChild( stats.domElement );
    
    		}
    
    		function removeMeshFromGroup( name ) {
    
    			group.children.forEach( ( child ) => {
    
    				if ( child.name === name ) {
    
    					group.remove( child );
    
    				}
    
    			} );
    
    		}
    
    		function render() {
    
    			renderer.render( scene, camera );
    			stats.update();
    			requestAnimationFrame( render );
    
    		}
    
    	</script>
    </body>
    </html>
    

    demo效果:

     

    展开全文
  • 抛弃N年前流行的960px设计,现在全球分辨率用的最多1366、1440、1024、1920,所以我采用了前2种分辨率的中间宽度1200px,而1024下又自适应宽度,所以不用担心1024。1200px阅读面积更宽,更大气。 三、纸质风格,...
  • MacBERT模型:来自哈工大SCIR实验室2020年的工作,改进了BERT模型的训练方法,使用全词掩蔽和N-Gram掩蔽策略适配中文表达,和通过用其相似的单词来掩盖单词,从而缩小训练前和微调阶段之间的差距 错误检测 字粒度...
  • 4.1.5 用过哪些Map类,都有什么区别,HashMap是线程安全的吗,并发下使用的Map是什么,他们内部原理分别是什么,比如存储方式,hashcode,扩容,默认容量等。 4.1.6 JAVA8的ConcurrentHashMap为什么放弃了分段锁,有...
  • LINGO软件的学习

    2009-08-08 22:36:50
    2.2 什么是集 集一群相联系的对象,这些对象也称为集的成员。一个集可能一系列产品、卡车或雇员。每个集成员可能有一个或多个与之有关联的特征,我们把这些特征称为属性。属性值可以预先给定,也可以未知的,...
  • php高级开发教程说明

    2008-11-27 11:39:22
    后在适当的地方加以例外处理,当写一个应用程序时,应该知道你的代码从事的是什么工作, 能够快速地从一点转到另一点—但其他人可能认为这并不容易。如果你从开发组的某个人手 中获得一个源文件并需要添加一些特征,...
  • 答:光纤的单模传输条件以第一高次(LP11)的截止频率而给出的。归一化截止频率为VC= /λ.对应着归一化截止频率的波长为截止波长,用λc表示, λc= λc= /2.40483 39.简述光源直接调制方式的主要优缺点. 答:...
  • RxJava是什么? RxJava的订阅流程 创建被观察者过程 订阅过程 RxJava的线程切换 LeakCanary 原理概述 简单示例 源码分析 LeakCanary运作流程 ButterKnife 简单示例 源码分析 模板代码解析 ButterKnife...
  • —— 如有您有好想法或者建议,欢迎加群交流 代码示例 Sa-Token的API调用非常简单,有多简单呢?以登录验证为例,你只需要: // 在登录时写入当前会话的账号id StpUtil.setLoginId(10001); // 然后在任意需要...
  • —— 如有您有好想法或者建议,欢迎加群交流 Sa-Token 功能结构图 Sa-Token 认证流程图 代码示例 Sa-Token的API调用非常简单,有多简单呢?以登录验证为例,你只需要: // 在登录时写入当前会话的账号id ...
  • 27、GC是什么? 为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象...
  • java 面试题 总结

    2009-09-16 08:45:34
    24、GC是什么? 为什么要有GC?  GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象...
  • 本书系统阐述组合数学基础、理论、方法和实例的优秀教材,出版近30年来多次改版,被MIT、哥伦比亚大学、UIUC、威斯康星大学等众多国外高校采用,对国内外组合数学教学产生了较大影n向,也相关学科的主要参考文献...
  • —— 如有您有好想法或者建议,欢迎加群交流 代码示例 sa-token的API调用非常简单,有多简单呢?以登录验证为例,你只需要: // 在登录时写入当前会话的账号id StpUtil.setLoginId(10001); // 然后在任意需要...
  • 各自含义是什么? 各 1)容量:交换单元所有入线可以同时送入的总的信息量 2)接口:即交换单元自己的信号接口标准 3)功能:点到点动能、同发功能,播功能。 4)质量:包括文换单元完成交换功能的况和信息经过交换单元的损份 ...
  • 字节跳动的算法面试题是什么难度?(第二弹) 《我是你的妈妈呀》 - 第一期 一文带你看懂二叉树的序列化 穿上衣服我就不认识你了?来聊聊最长上升子序列 你的衣服我扒了 - 《最长公共子序列》 一文看懂《最大子序列...
  • 精通Oracle PL/SQL--详细书签版

    热门讨论 2012-08-21 13:06:28
    据我所知,它们中没有一本书可以作为风靡全球的畅销书摆放于哈利·波特那些书的旁边,那么究竟是什么鼓舞着我们这作者走到一起写出关于这个主题的第39本书呢?.  原因是,无论可用的图书如何过剩,我们仍然在...
  • c语言编写单片机技巧

    2009-04-19 12:15:17
    一名武汉大学电子科技大3的学生,学了电子线路、数字逻辑、汇编和接口、C语言,但是总是感觉很迷茫,觉好象什么都不会。怎么办? 答:大学过程一个理论过程,实践的机会比较少,往往会造成理论与实践相...
  • 零切片、空切片、nil切片是什么 slice深拷贝和浅拷贝 map触发扩容的时机,满足什么条件时扩容? map扩容策略是什么 自定义类型切片转字节切片和字节切片转回自动以类型切片 make和new什么区别 slice ,map,chanel...
  • 本书目前已经出版的唯一一本深入探讨Ajax开发中的架构问题的著作,这使得它显得卓而不。如果不去深入研究Ajax开发中的架构问题,Ajax开发领域将会再现J2EE开发领域早年的那种混乱局面,本书将会使得Ajax开发秩序...
  • 11群是四个群中最小的群,其中继计次表位于缓冲区的首位,打完电话后查询内存发现出中继群号在内存中是正确的,取完话单后再查就不正确了。 结 论: 话单池的一个备份指针Pool_head_1和中继计次表的头指针重合,...
  • Symphony([ˈsɪmfəni],n.交响乐)一个现代化的社区平台,因为它: 实现了面向内容讨论的论坛 包含了面向用户分享、交友、游戏的社交网络 集成了聚合独立博客的能力,共建共享优质资源 并且 100% 开源 ...
  • 框架还支持使用KCP协议,KCP也可靠UDP协议,据说比ENET性能更好,使用kcp请注意,需要自己心跳机制,否则20秒没收到包,服务端将断开连接。协议可以无缝切换。 11. 3D Recast寻路功能 可以Unity导出场景数据,...
  • 4·3 通项是n的整式的数列 4·4 分数项数列 4·5 Σanxn(an等差数列) 4·6 二重数列与相似形 5.数学归纳法 5·1 归纳公理 5·2 数学归纳法 6.数列的收敛、发散 6·1 数列收敛、发散的定义 6·2 关于收敛数列的定理...
  • 4·3 通项是n的整式的数列 4·4 分数项数列 4·5 Σanxn(an等差数列) 4·6 二重数列与相似形 5.数学归纳法 5·1 归纳公理 5·2 数学归纳法 6.数列的收敛、发散 6·1 数列收敛、发散的定义 6·2 关于收敛数列的定理...

空空如也

空空如也

1 2
收藏数 33
精华内容 13
关键字:

模n加群是什么