`
xhload3d
  • 浏览: 209749 次
社区版块
存档分类
最新评论

基于HT的CSG功能构建HTML5的3D书架

阅读更多

构造实体几何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。

Screen Shot 2014-12-25 at 12.19.17 AM

回到我们今天要搞的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书籍,强烈推荐!

Screen Shot 2014-12-25 at 12.22.57 AM

书架两边分别摆放了两个不同风格的小书台,通过上图我拖拽改变了蓝色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);
				  
}   

 

4
1
分享到:
评论

相关推荐

    csg.zip_OpenGL CSG_csg_csg opengl_opengl c

    2. **CSG原理**:掌握如何通过布尔运算(并集、差集、交集)组合基本几何体以构建复杂形状。 3. **C语言编程**:熟悉C语言语法,能够阅读和修改源代码。 4. **OpenGL编程**:学习如何使用OpenGL API进行图形渲染,...

    Unity CSG插件

    Unity CSG插件是一款在Unity Asset Store中可以下载到的扩展工具,专门用于提升游戏开发中的3D建模效率。Constructive Solid Geometry(CSG)是一种几何构造技术,它允许开发者通过基本形状(如球体、立方体、圆柱体...

    在Julia中构建 CSG 对象的算法和语法_julia_代码_下载

    在Julia中构建 CSG 对象的算法和语法 ConstructiveGeometry.jl提供通过基本图元和 CSG 操作定义 2d 形状和 3d 实体的功能,以及用于显示这些对象并输出到 SVG 或 STL 文件的功能。 以下功能现在应该主要工作: 2d...

    Unity CSG 布尔运算插件 模型打孔 模型打洞

    布尔运算是一种在几何建模中广泛使用的技巧,通过合并、相减或相交不同的3D形状来构建新的模型。在Unity中,CSG插件提供了这种功能,极大地拓展了游戏物体的设计可能性,尤其适用于制作具有精细结构的游戏环境或道具...

    csg.rar_CSg树实现_csg树_csg树是什么_csg树特征草图_实现csg树

    CSG树,全称为Constructive Solid Geometry(构造体素几何),是一种在计算机图形学中用于构建和操作3D几何形状的技术。它通过结合基本几何体(如立方体、球体、锥体等)来创建复杂的模型,这些基本几何体可以进行交...

    csg.c.rar_OpenCSG example_OpenGL CSG_OpenGL 布尔_csg c_布尔

    **OpenCSG** 是一个开源库,它提供了基于OpenGL的构造几何(CSG)操作。这个库使得用户能够以编程方式创建、编辑和操作3D几何体,并且支持高效的布尔运算。在提供的源代码**csg.c**中,我们可以看到如何利用OpenCSG...

    Unity 布尔算法插件CSG

    CSG允许您通过执行对象之间的减法、联合和交集来创建新的网格。您可以在Unity编辑器或运行时执行操作。得到的几何形状保留了原始网格的纹理UV坐标。该程序还按预期处理旋转和缩放的对象,适用于具有多个材料和子网格...

    csg.rar_csg树_csg树是什么_csg树求并_opencsg_树

    CSG(Constructive Solid Geometry)树是一种在计算机图形学中用于构建复杂三维形状的技术。它通过组合基本的几何实体,如立方体、球体、圆柱体等,使用布尔运算(交、并、补)来创建更复杂的模型。在本案例中,"csg...

    Unity Boolean CSG插件的使用

    Unity Boolean CSG插件的使用

    CSG550方案的国网表计量代码

    基于CSG550方案的国网表的计量代码,非常值得参考

    CSG324 Package Drawing (Chip-Scale BGA).pdf

    "CSG324 Package Drawing (Chip-Scale BGA)" 本资源主要介绍了Xilinx公司的CSG324封装(Chip-Scale BGA)包drawing的详细信息,包括封装的结构、尺寸、引脚分布等信息。 CSG324封装简介 CSG324封装是Xilinx公司...

    CSG-Stump A Learning Friendly CSG-Like Representation.pdf

    CSG-Stump是一种学习友好的、类似CSG(Constructive Solid Geometry)的形状解析表示方法,旨在从点云数据中生成可解释且紧凑的3D形状表示。在计算机图形学和计算机视觉领域,形状建模和理解是核心研究方向,因为...

    Carve CSG 几何造型库

    Carve是一个C++库,用于执行两个任意多边形网格之间的布尔操作。 支持标准的联合和交叉操作,以及对称和非对称差异。... Carve csg还可以在面间任意插值,这意味着CSG操作不需要删除颜色,纹理坐标或其他数据。

    CSG for unity

    Constructive Solid Geometry allows you to create new meshes by performing Subtraction, Union and Intersection between objects.

    基于CSG和MCNP的探测器无源效率刻度软件架构设计.doc

    基于CSG和MCNP的探测器无源效率刻度软件架构设计.doc

    unity Realtime CSG 建模工具

    Realtime CSG is a 'BSP' level design tool that allows you to Intuitively & rapidly create levels.

    csg.rar_csg_sub

    这是一个用于创建和操作3D几何形状的技术,它通过基本形状的布尔运算(如并集、交集和差集)来构建复杂的几何模型。 描述中提到的"正二十面体与球的(OR)组合(AND)组合(SUB)组合"是指在CSG中使用的基本几何体——正...

    csg.rar_csg

    开发基于Linux的CSG,可以充分利用其丰富的开发工具和强大的网络支持,同时降低运维成本。 2. **控制信令**:在通信网络中,控制信令用于建立、维护和终止通信连接,如通话或数据传输。CSG在此过程中起到桥梁作用,...

Global site tag (gtag.js) - Google Analytics