构造实体几何CSG全称Constructive solid geometry,是3D计算机图形学中构建模型的常用技术,可通过合并Union、相减Subtraction和相交Intersction的三种取集的逻辑运算,将立方体、圆柱体和棱柱等简单的基础模型,嵌套组合成更复杂三维模型。
CSG的算法这些年来已有各种语言平台版本实现,C++版主流的是 http://opencsg.org/ 已有众多基于该开源类库的应用案例,JavaScript语言较早版实现 http://evanw.github.io/csg.js/ 影响较广,很多其他js衍生版都是基于该版本进行改进完善,包括Java版的实现 https://github.com/miho/JCSG ,可参考基于JavaFX的3D打印IDE https://github.com/miho/JFXScad ,提起JavaFX视乎这些年完全消失在程序员视野毫无声息,但还是有一群拥护者持续在使用着如今地位有点尴尬的JavaFX。
回到我们今天要搞的3D书架例子,我们将基于HT for Web的3D引擎来实现,HT已经内置了CSG功能的模型封装,我们通过构建CSGNode图元对象,该类型图元可对Host吸附的图元进行CSG技术的合集、并集和补集的三种操作,一般运用中裁剪的方式较为常用,因此CSGNode默认对Host图元的操作就是裁剪。
上图的例子效果可看出我们构建了一个DataModel数据模型,该模型绑定了一个TreeView树组件和两个Graph3dView的三维组件,上部分的Graph3dView组件添加了VisibleFunc的可见过滤器,隐藏了如下部分的Graph3dView中蓝色立方体图元,这些蓝色立方体图元就是CSGNode,其作用就是用来裁剪其吸附的书架Shelf对象,因此一般在3D编辑器状态下才需要出现,运行时科如上部分Graph3dView组件那样,通过添加可见过滤器将其隐藏,这样就实现了有凹槽可摆放书籍内容的3D书架效果,本例我们作为示例仅放了一本《CSS3 The Missing Manual》,这本书其实是由一个六面体,front面显示了书籍贴图,然后旋转一定角度进行摆放,btw《CSS3 The Missing Manual》第三版是本很不错的CSS书籍,强烈推荐!
书架两边分别摆放了两个不同风格的小书台,通过上图我拖拽改变了蓝色CSGNode图元的位置,大家通过两张图的对比能更直观的体会到CSG的操作效果,玻璃门开关以及相册效果都是直接利用HT for Web的3D引擎提供的模型,通过设置透明度、相片贴图和旋转动画等呢只功能参数即可。
以下是该HT for Web的3D例子的所有JavaScript代码供参考:http://v.youku.com/v_show/id_XODU2MTQ4NjI4.html
ht.Default.setImage('ben12', { width: 100, height: 50, comps: [ { type: 'image', name: 'ben1', rect: [0, 0, 50, 50] }, { type: 'image', name: 'ben2', rect: [50, 0, 50, 50] } ] }); function init(){ dm = new ht.DataModel(); treeView = new ht.widget.TreeView(dm); gv1 = new ht.graph3d.Graph3dView(dm); gv2 = new ht.graph3d.Graph3dView(dm); splitView = new ht.widget.SplitView(gv1, gv2, 'v', 0.6); mainSplit = new ht.widget.SplitView(treeView, splitView, 'h', 0.27); view = mainSplit.getView(); view.className = 'main'; document.body.appendChild(view); window.addEventListener('resize', function (e) { mainSplit.invalidate(); }, false); gv1.setMoveStep(30); gv1.setGridVisible(true); gv1.setEye(0, 100, 1000); gv1.setCenter(0, 200, 0); gv1.pan(0, 100, true); gv1.getLabel = function(){ return null; }; gv1.getBrightness = function(data){ return null; }; gv1.setVisibleFunc(function(data){ if(data.showMe){ return true; } if(data instanceof ht.CSGNode && data.getHost()){ return false; } return true; }); gv2.setMoveStep(30); gv2.setEditable(true); gv2.setGridVisible(true); gv2.setEditable(true); gv2.pan(0, 200, true); gv2.getLabel = function(){ return null; }; initShelf1(); initShelf2(); initShelf3(); treeView.expandAll(); var angle = 0; setInterval(function(){ angle += Math.PI/40; earth.r3(0, angle, 0); photos.s('dw.angle', angle); }, 50); } function initShelf1(){ var shelf = new ht.CSGNode(); shelf.s3(500, 400, 120); shelf.p3(0, 200, 0); shelf.setName('shelf1'); shelf.s({ 'all.color': '#E5BB77' }); dm.add(shelf); for(var i=0; i<2; i++){ for(var j=0; j<5; j++){ var clipNode = new ht.CSGNode(); clipNode.setHost(shelf); clipNode.s3(80, 100, 120); clipNode.p3(-200+j*100, 340-i*120, 20); clipNode.setName('substract-'+i+'-'+j); clipNode.s('batch', 'tt'); clipNode.setParent(shelf); dm.add(clipNode); } } var leftNode = new ht.CSGNode(); leftNode.setHost(shelf); leftNode.s3(23, 380, 100); leftNode.p3(-255, 200, 0); leftNode.setName('substract left'); leftNode.setParent(shelf); dm.add(leftNode); var rightNode = new ht.CSGNode(); rightNode.setHost(shelf); rightNode.s3(23, 380, 100); rightNode.p3(255, 200, 0); rightNode.setName('substract right'); rightNode.setParent(shelf); dm.add(rightNode); var bottomNode = new ht.CSGNode(); bottomNode.setHost(shelf); bottomNode.s3(480, 140, 140); bottomNode.p3(0, 80, 0); bottomNode.setName('substract bottom'); bottomNode.setParent(shelf); dm.add(bottomNode); var topNode = new ht.CSGNode(); topNode.setHost(shelf); topNode.s3(480, 10, 100); topNode.p3(0, 400, 0); topNode.setName('union top'); topNode.s('attach.operation', 'union'); topNode.setParent(shelf); dm.add(topNode); var book = new ht.Node(); book.setName('CSS3: The Missing Manual'); book.s3(60, 80, 8); book.p3(-100, 210, 20); book.r3(-Math.PI/6, Math.PI/5, 0); book.setIcon('book'); book.s({ 'front.image': 'book', 'back.color': 'white', 'left.color': 'white', 'all.color': 'gray' }); book.setHost(shelf); book.setParent(shelf); dm.add(book); } function initShelf2(){ var shelf = new ht.CSGNode(); shelf.s3(120, 240, 120); shelf.p3(0, 120, 0); shelf.setName('shelf2'); shelf.s({ 'all.color': '#805642', 'csg.color': 'yellow', 'csg.reverse.flip': true }); dm.add(shelf); var clipNode = new ht.CSGNode(); clipNode.setName('shelf2-substract-up'); clipNode.s3(100, 100, 130); clipNode.p3(0, 180, 0); clipNode.setHost(shelf); clipNode.s('attach.cull', true); clipNode.setParent(shelf); dm.add(clipNode); clipNode = new ht.CSGBox(); clipNode.setName('CSGBox-Expand-Left'); clipNode.s3(100, 100, 120); clipNode.p3(0, 65, 0.1); clipNode.setHost(shelf); clipNode.showMe = true; clipNode.s({ 'all.visible': false, 'front.visible': true, 'front.toggleable': true, 'front.reverse.flip': true, 'front.transparent': true, 'front.end': Math.PI * 0.7, 'front.color': 'rgba(0, 50, 50, 0.7)' }); clipNode.setParent(shelf); clipNode.setFaceExpanded('front', true, true); dm.add(clipNode); earth = new ht.Node(); earth.setName('earth'); earth.setIcon('earth'); earth.s3(70, 70, 70); earth.p3(0, 50, 0); earth.s({ 'shape3d': 'sphere', 'shape3d.image': 'earth' }); earth.setHost(shelf); earth.setParent(shelf); dm.add(earth); shelf.t3(-360, 0, 50); shelf.r3(0, Math.PI/7, 0); } function initShelf3(){ var shelf = new ht.CSGNode(); shelf.s3(120, 240, 120); shelf.p3(0, 120, 0); shelf.setName('shelf3'); shelf.setIcon('ben'); shelf.s({ 'all.image': 'brick', 'all.uv.scale': [2, 4], 'top.uv.scale': [2, 2], 'bottom.uv.scale': [2, 2], 'csg.image': 'ben', 'csg.blend': 'yellow' }); dm.add(shelf); photos = new ht.DoorWindow(); photos.setName('DoorWindow-Photos'); photos.setIcon('ben12'); photos.s3(110, 100, 130); photos.p3(5, 180, 0); photos.setHost(shelf); photos.showMe = true; photos.s({ 'bottom.uv': [1,1, 1,0, 0,0, 0,1], 'bottom.uv.scale': [1, 1], 'left.uv.scale': [3, 3], 'top.uv.scale': [2, 2], 'dw.s3': [0.8, 0.9, 0.05], 'dw.t3': [0, -5, 0], 'dw.axis': 'v', 'dw.toggleable': false, 'front.image': 'ben1', 'back.image': 'ben2', 'all.color': '#F8CE8B' }); photos.setParent(shelf); dm.add(photos); var clipNode = new ht.CSGBox(); clipNode.setName('CSGBox-Expand-Top'); clipNode.s3(100, 100, 120); clipNode.p3(0, 65, 0.1); clipNode.setHost(shelf); clipNode.showMe = true; clipNode.s({ 'all.visible': false, 'front.visible': true, 'front.color': 'red', 'front.transparent': true, 'front.opacity': 0.7, 'front.reverse.flip': true, 'front.toggleable': true, 'front.axis': 'top', 'front.end': Math.PI * 0.4 }); clipNode.setParent(shelf); clipNode.setFaceExpanded('front', true, true); dm.add(clipNode); shelf.t3(360, 0, 50); shelf.r3(0, -Math.PI/7, 0); }
相关推荐
2. **CSG原理**:掌握如何通过布尔运算(并集、差集、交集)组合基本几何体以构建复杂形状。 3. **C语言编程**:熟悉C语言语法,能够阅读和修改源代码。 4. **OpenGL编程**:学习如何使用OpenGL API进行图形渲染,...
Unity CSG插件是一款在Unity Asset Store中可以下载到的扩展工具,专门用于提升游戏开发中的3D建模效率。Constructive Solid Geometry(CSG)是一种几何构造技术,它允许开发者通过基本形状(如球体、立方体、圆柱体...
在Julia中构建 CSG 对象的算法和语法 ConstructiveGeometry.jl提供通过基本图元和 CSG 操作定义 2d 形状和 3d 实体的功能,以及用于显示这些对象并输出到 SVG 或 STL 文件的功能。 以下功能现在应该主要工作: 2d...
布尔运算是一种在几何建模中广泛使用的技巧,通过合并、相减或相交不同的3D形状来构建新的模型。在Unity中,CSG插件提供了这种功能,极大地拓展了游戏物体的设计可能性,尤其适用于制作具有精细结构的游戏环境或道具...
CSG树,全称为Constructive Solid Geometry(构造体素几何),是一种在计算机图形学中用于构建和操作3D几何形状的技术。它通过结合基本几何体(如立方体、球体、锥体等)来创建复杂的模型,这些基本几何体可以进行交...
**OpenCSG** 是一个开源库,它提供了基于OpenGL的构造几何(CSG)操作。这个库使得用户能够以编程方式创建、编辑和操作3D几何体,并且支持高效的布尔运算。在提供的源代码**csg.c**中,我们可以看到如何利用OpenCSG...
CSG允许您通过执行对象之间的减法、联合和交集来创建新的网格。您可以在Unity编辑器或运行时执行操作。得到的几何形状保留了原始网格的纹理UV坐标。该程序还按预期处理旋转和缩放的对象,适用于具有多个材料和子网格...
CSG(Constructive Solid Geometry)树是一种在计算机图形学中用于构建复杂三维形状的技术。它通过组合基本的几何实体,如立方体、球体、圆柱体等,使用布尔运算(交、并、补)来创建更复杂的模型。在本案例中,"csg...
Unity Boolean CSG插件的使用
基于CSG550方案的国网表的计量代码,非常值得参考
CSG-Stump是一种学习友好的、类似CSG(Constructive Solid Geometry)的形状解析表示方法,旨在从点云数据中生成可解释且紧凑的3D形状表示。在计算机图形学和计算机视觉领域,形状建模和理解是核心研究方向,因为...
Carve是一个C++库,用于执行两个任意多边形网格之间的布尔操作。 支持标准的联合和交叉操作,以及对称和非对称差异。... Carve csg还可以在面间任意插值,这意味着CSG操作不需要删除颜色,纹理坐标或其他数据。
Constructive Solid Geometry allows you to create new meshes by performing Subtraction, Union and Intersection between objects.
基于CSG和MCNP的探测器无源效率刻度软件架构设计.doc
这是一个用于创建和操作3D几何形状的技术,它通过基本形状的布尔运算(如并集、交集和差集)来构建复杂的几何模型。 描述中提到的"正二十面体与球的(OR)组合(AND)组合(SUB)组合"是指在CSG中使用的基本几何体——正...
开发基于Linux的CSG,可以充分利用其丰富的开发工具和强大的网络支持,同时降低运维成本。 2. **控制信令**:在通信网络中,控制信令用于建立、维护和终止通信连接,如通话或数据传输。CSG在此过程中起到桥梁作用,...
Realtime CSG is a 'BSP' level design tool that allows you to Intuitively & rapidly create levels.
7. **API设计**:良好的API设计是任何库的关键,csg-gwt 应该提供清晰、易于使用的接口,使得开发者能够方便地集成3D建模功能到他们的GWT应用中。 8. **示例和文档**:为了帮助开发者快速上手,项目通常会包含示例...