1、场景的基本功能
按照书籍的写法,点击添加立方体按钮,发现scene的children的length加1了,但是没有立方体绘制出来。猜测是每次添加立方体都需要重新调用renderer.render(scene, camera),给立方体方法追加该调用,发现立方体还是绘制不出。打印新增立方体的信息:
发现位置x的值为NaN。按书籍的写法,以为直接使用planeGeometry的width和height,打印planeGeometry信息,发现其下没有属性width和height:
需要用planeGeometry.parameters.width替代planeGeometry.width,planeGeometry.parameters.height替代planeGeometry.height。
2、使用材质覆盖属性
书籍说scene.overrideMaterial覆盖所有物体的材质,初步看到的时候,想着可以不用声明地面、立方体的材质,后面向Mesh有传两个值,这样材质的声明就省下了。后面又想“声明Mesh时传两个值是必须的吗?”,尝试将材质的传参省略,发现也可以,这样前面的猜想就成立了。
像前端很多特性配置会覆盖共用配置,要是我将scene.overrideMaterial的赋值放前面,立方体的材质放后面,是否后面声明的优先级更高?尝试发现,立方体设置的材质无法覆盖scene.overrideMaterial设置的材质。
3、集合对象的属性和函数
A、根据github的04-geometries.html敲代码,发现报错:
根据THREE的官方文档,发现ConvexGeometry需要引入,其位置在”import {ConvexGeometry} from ‘three/addons/geometries/ConvexGeometry.js’”。
B、本地项目报错:
看git的代码,有引入ParametricGeometries.js,在官网上查找没有找到与ParametricGeometries相关的内容,文档上导入的是ParametricGeometry.js,其位置在”import {ConvexGeometry} from ‘three/addons/geometries/ParametricGeometry.js’”,导入后还是报上面的错误,感觉要将THREE.ParametricGeometries.mobiu3d改成ParametricGeometry.mobiu3d,修改后报错变了:
将THREE.ParametricGeometry改成ParametricGeometry后,就可以了。
C、本地项目报错:
初步猜想,需要将createMultiMaterialObject的调用者引入进来,并去掉调用者的前缀”THREE.”。根据官网引入”import * as SceneUtils from ‘three/addons/utils/SceneUtils.js’”,去掉前缀,更新页面后可以正常绘制了。
4、几何对象的属性和函数
A、根据github对应示例编写代码,本地项目报错:
猜测需要单独引入Face3的文件,看有的说法说Face3在的”three/addons/deprecated/Geometry.js”,找了下,发现没有deprecated这个文件夹。后面看到新说法Face3被移弃,用Face替代。
B、项目报错:
网上说THREE.Geometry不支持了,需要用BufferGeometry替代。将THREE.Geometry改成THREE.BufferGeometry后报错没有了。
C、项目报错:
在B部分,geom的类型为BufferGeometry,翻了下BufferGeometry.js文件,发现其确实没有computeFaceNormals,对比了下功能,感觉其被normalizeNormals替换。
D、项目报错:
根据C部分将computeFaceNormals改成normalizeNormals,产生新的报错。感觉是BufferGeometry没有东西导致。书籍给geom的属性vertices和faces赋值,BufferGeometry里没有这两个属性。Geometry.vertices要用BufferGeometry.attributes.position.array替换,array存放所有点的一维数组,根据itemSize的数值设置点是二维还是三维的,可以通过”geom.attributes.array.position.array[0] = 1”赋值,也可以通过”geom.setAttribute(‘position’, content)”赋值。
给geom.attributes.array.position.array添加内容后,发现报错依然存在,将normalizeNormals的执行注释掉。绘制效果如下:
调整点7或点8,发现可以绘制三个三角形,感觉其补了(0, 0, 0)的点。书籍绘制的绘制效果要是长方体。网上有说法Geometry.faces用BufferGeometry.index.array替换,可以用BufferGeometry.setIndex修改其内容。
将normalizeNormals执行放开,发现还是报错。看BufferGeometry还有一个方法computeVertexNormals方法,在normalizeNormals执行前执行computeVertexNormals方法,发现没有报错。将normalizeNormals的执行去除,发现绘制效果没有变化。
E、本地报错
看官网,Scene的内容很简单,官网上没有写Scene有children,但在控制台上打印scene.children是有内容。scene.children返回Scene.add的所有内容,可以自己写getChildByName方法。
用数组的find方法查找scene.children中对应的name相同的元素,用scene.remove移除,发现移除失败。在之前添加删除立方体时,使用scene.remove是可以移除的,其传入的参数是scene.children[scene.children.length - 1]。是不是其要求传入的内容要和scene.chilldren某一项的指向相同的地址呢?将移除操作内容改成scene.remove(scene.children[index]),index为scene.children中name为clone的下标,更新后发现scene.remove移除成功了。
Js的find函数,其功能大多写返回通过测试的数组的第一个元素,之前对其理解为若元素为引用类型,则其返回值为该元素的指向地址。自己做了下测试,发现js的find返回的确实的引用地址。。。后面调整了下代码,发现也可以删除find返回的内容了。。。后面发现是用scene.getChildByName调整,自己写的要两个参数,少了一个参数。。。
后面发现Scene有方法getObjectByName,可以用来替代Scene.getChildByName。