学习笔记(5)ht for web----关于吸附父图元

知识回顾:
Node#getHost()和Node#setHost(node)获取和设置吸附的图元对象
Node#getAttaches()返回目前吸附到该图元的所有对象,返回ht.List链表对象,无吸附对象时返回空
Node#isHostOn(node)判断该图元是否吸附到指定图元对象上
Node#isLoopedHostOn(node)判断该图元是否与指定图元相互形成环状吸附,例如A吸附B,B吸附C,C又吸附回A,则A,B和C图元相互环状吸附

参看代码解释:
效果图:


Paste_Image.png
var createInsideWall = function(dataModel) {



    ht.Default.setImage('door', 'images/door_left.png');
    ht.Default.setImage('ldoor', 'images/ldoor.jpg');
    ht.Default.setImage('rdoor', 'images/rdoor.jpg');
    ht.Default.setImage('winImage', 'images/chuang.jpg');   
    ht.Default.setImage('ceramic_tile', 'images/ceramic_tile.png');
    
    
    //  wall.setPoints({})里面的左边点要按顺序绘制
    //在2d平面图上,正方向是向右、向下
    //setPoints结合setTall方法类似于s3的作用
    //内墙相关参数

    var wall = new ht.CSGShape();
    //参数对应关系x:width、y:height;    
    var x1=-2000,x2=2000,x3=2000,x4=-2000,y1=-1500,y2=-1500,y3=1500,y4=1500;
    wall.setPoints([{
        x: x1,
        y: y1
    }, {
        x: x2,
        y: y2
    }, {
        x: x3,
        y: y3
    }, {
        x: x4,
        y: y4
    }]);
    wall.setPosition(0,-1500);
    wall.setTall(500); //设置墙体高度
    wall.setElevation(wall.getTall() / 2); //把墙体往地板上部上移tall的一半高度
    wall.setClosePath(true);
    wall.setThickness(50);
    wall.s({
        'shape.border.width': 20,
        'shape.border.color': '#898989',
        'all.color':'white',
        'back.image': 'ceramic_tile',
        'back.uv.scale': [1, 10],
        'repeat.uv.length': 80,//改变图片重复问题,同样可以解决机器区域的图片问题--重复贴墙纸
        'front.color': 'lightgray',
        'csg.color': '#DDDDDD'
    });
    dataModel.add(wall);
    
    
    /**************************挖空一半正前方的墙体***************************/
    var frontWall = new ht.CSGNode();
    frontWall.setHost(wall);
    frontWall.setParent(wall);
    frontWall.setWidth(4000);
    frontWall.setHeight(40);
    frontWall.setTall(wall.getTall()/2);
    frontWall.setElevation(wall.getTall()*0.75);
    frontWall.s({
        'attach.index':2,
        'attach.offset.relative':true,
        'attach.offset':0.5,
        'all.visible':false
    });
    dataModel.add(frontWall);

/*
 
 * 因为ht.CSGNode继承于ht.Node,
 * 因为ht.DoorWindow继承于ht.CSGNode,
 * 所以ht.DoorWindow具有前两者的所有属性方法,包括挖空墙的方法,
 * 所以在创建窗户时,不需要再进行挖空的操作。
 * 
 * */

//  //挖空门
//  var HollowDoor = new ht.CSGNode();
//  HollowDoor.setHost(wall);
//  HollowDoor.setParent(wall);
//  HollowDoor.setWidth(240);
//  HollowDoor.setHeight(30);
//  HollowDoor.setTall(200);
////  HollowDoor.s3(240,200,30)
//  HollowDoor.setElevation(70);
//  HollowDoor.s({
//      'attach.index': 2, 
//      'attach.offset.relative': true,
//      'attach.offset': 0.864, 
//      'all.visible': false
//  });
//  dataModel.add(HollowDoor);


    var door_left = new ht.DoorWindow();
    door_left.setHost(wall);
    //  doorleft.setParent(wall);
    door_left.setWidth(120);
    door_left.setTall(200);
    door_left.setElevation(door_left.getTall() / 2+10); 
    door_left.s({

        'attach.index': 2,//根据setPoints的左边点的顺序来确定index的值
        'attach.offset.relative': true,
        'attach.offset': 0.864,//根据绘制的顺序,距离上一个点的距离(0~1)
        'front.image': 'ldoor',
        'back.image': 'ldoor',
        'all.color': 'white',
//      'all.blend': '#A95A10',
        'front.uv': [1, 0, 1, 1, 0, 1, 0, 0],
        'back.transparent': true,
        'dw.axis': 'right',
        'dw.s3': [1, 1, 0.1]

    })
    dataModel.add(door_left);




    var door_right = new ht.DoorWindow();
    door_right.setHost(wall);
    //  doorleft.setParent(wall);
    door_right.setWidth(120);
    door_right.setTall(200);
    door_right.setElevation(door_right.getTall()/2+10);
    door_right.s({
        'attach.index': 2,
        'attach.offset.relative': true,//相对定位
        'attach.offset': 0.81,
        'front.image': 'rdoor',
        'back.image': 'rdoor',
        'all.color': 'white',
        'front.uv': [0,1, 0,0, 1,0, 1,1],
        'back.uv': [1,0, 1,1, 0,1, 0,0],
        'dw.axis': 'right',//右手边打开门
        'dw.s3': [1, 1, 0.1]//窗户的透明度的参数

    })
    dataModel.add(door_right);
    
    
    /***************************************创建窗户和窗台相关操作*********************/
    //挖空窗
    
    for(i=0;i<3;i++){
        var offset=0.17, offsetX=0.32;
         offset+=offsetX*i;
         createWindowOnWall(offset);
    }
    
     function createWindowOnWall(offset){
    
    var windowH=400;
    var windowW=600;    
    var insideWindow =new ht.CSGNode();
    insideWindow.setHost(wall);
    insideWindow.setParent(wall);
    insideWindow.setWidth(windowW);
    insideWindow.setHeight(30);
    insideWindow.setTall(windowH);
    insideWindow.setElevation(insideWindow.getTall()/2+25);
    insideWindow.s({
        'attach.index':0,
        'attach.offset.relative':true,
        'attach.offset':offset,
        'all.visible':false
    })
    dataModel.add(insideWindow);

   //创建窗台
    var table =new ht.Node();
       noteStyle = {
                    'note': '英雄联盟',
                    'note.position': 17,
                    'note.offset.x': 0,
                    'note.offset.y': 0                   
                };
    table.setHost(wall);
    table.setParent(wall);
    table.s3(windowW,10,40);
    table.setElevation(20);
    table.s(noteStyle);
    table.s({
        'attach.index':0,
        'attach.offset.relative':true,
        'attach.offset':offset,
        'all.color':'white',
         'attach.gap': -20//z轴偏移
    })
    dataModel.add(table);
    
    //创建玻璃
    var windowInside =new ht.Node();
    windowInside.setHost(wall);
    windowInside.setParent(wall);
//  windowInside.setImage('winImage');//注意区分setImage方法与all.image之间的区别
    windowInside.setWidth(windowW);
    windowInside.setHeight(15);
    windowInside.setTall(windowH);
    windowInside.open = false;
    //旋转角度
    windowInside.angle = Math.PI / 4;
    windowInside.window = true; //旋转方向
    windowInside.setElevation(windowInside.getTall()/2+25);
    windowInside.s({    
        'attach.index': 0,
        'attach.offset.relative': true,//相对定位
        'attach.offset':offset,
        'front.image':'winImage',
        'back.image':'winImage',        
        'dw.s3': [1, 1, 0.1],//窗户的透明度的参数
    })
    dataModel.add(windowInside);
    
    }
/************************************************************/  
    
    
    //************************创建柱子*************************
    for(i=0;i<4;i++){
        var pillarX=-1925,pillar=1280,pillarZ=-2970;
        
        pillarX+=pillar*i;
        createPillar(pillarX,250,pillarZ);
    
    }

    function createPillar(x,y,z){
        var node=new ht.Node();
        node.setHost(wall);
        node.setParent(wall);
        node.p3(x,y,z);
        node.s3(150,495,100);
        node.s({
            'all.color':'white'
        });
        dataModel.add(node);
        
    }
    /****************************************************************************/
    
            
    /*****************************创建左右两侧的大门**********************/
    var index_l=3,index_r=1;    
    for(i=0;i<2;i++){
        if(i==0){
            createBigGate(index_r);
        }
        if(i==1){
            createBigGate(index_l);
        }
    }
    function createBigGate(index){
    var bigGate1 =new ht.DoorWindow();
    bigGate1.setHost(wall);
    bigGate1.setParent(wall);
    bigGate1.setWidth(300);
    bigGate1.setHeight(30);
    bigGate1.setTall(380);
    bigGate1.setToolTip('Double click to open the window');
    bigGate1.setElevation(bigGate1.getTall()/2+15);
    bigGate1.s({
        'attach.index': index,
        'attach.offset.relative': true,//相对定位
        'attach.offset': 0.2,
        'front.image': 'ldoor',
        'back.image': 'ldoor',
        'all.color': 'white',
        'front.uv': [0,1, 0,0, 1,0, 1,1],
        'back.uv': [1,0, 1,1, 0,1, 0,0],
        'dw.axis': 'left',
        'dw.s3': [1, 1, 0.1]//窗户的透明度的参数
    });
    
    dataModel.add(bigGate1);
    
    var bigGate2 =new ht.DoorWindow();
    bigGate2.setHost(wall);
    bigGate2.setParent(wall);
    bigGate2.setWidth(300);
    bigGate2.setHeight(30);
    bigGate2.setTall(380);
    bigGate2.setElevation(bigGate2.getTall()/2+15);
    bigGate2.s({
        'attach.index': index,
        'attach.offset.relative': true,
        'attach.offset': 0.3,
        'front.image': 'rdoor',
        'back.image': 'rdoor',
        'all.color': 'white',
        'front.uv': [0,1, 0,0, 1,0, 1,1],
        'back.uv': [1,0, 1,1, 0,1, 0,0],
        'dw.axis': 'right',
        'dw.s3': [1, 1, 0.1]
    });
    
    dataModel.add(bigGate2);
    
    
    var bigGate3 =new ht.DoorWindow();
    bigGate3.setHost(wall);
    bigGate3.setParent(wall);
    bigGate3.setWidth(300);
    bigGate3.setHeight(30);
    bigGate3.setTall(380);
    bigGate3.setElevation(bigGate3.getTall()/2+15);
    bigGate3.s({
            'attach.index': index,
        'attach.offset.relative': true,//相对定位
        'attach.offset': 0.7,
        'front.image': 'ldoor',
        'back.image': 'ldoor',
        'all.color': 'white',
        'front.uv': [0,1, 0,0, 1,0, 1,1],
        'back.uv': [1,0, 1,1, 0,1, 0,0],
        'dw.axis': 'left',
        'dw.s3': [1, 1, 0.1]//窗户的透明度的参数
    });
    
    dataModel.add(bigGate3);
    
    var bigGate4 =new ht.DoorWindow();
    bigGate4.setHost(wall);
    bigGate4.setParent(wall);
    bigGate4.setWidth(300);
    bigGate4.setHeight(30);
    bigGate4.setTall(380);
    bigGate4.setElevation(bigGate4.getTall()/2+15);
    bigGate4.s({
        'attach.index': index,
        'attach.offset.relative': true,
        'attach.offset': 0.8,
        'front.image': 'rdoor',
        'back.image': 'rdoor',
        'all.color': 'white',
//      'all.blend': '#A95A10',
        'front.uv': [0,1, 0,0, 1,0, 1,1],
        'back.uv': [1,0, 1,1, 0,1, 0,0],
//      'back.transparent': true,
//      'front.transparent': true,
//      'all.reverse.cull': true,
        'dw.axis': 'right',
        'dw.s3': [1, 1, 0.1]
    });
    
    dataModel.add(bigGate4);
   }
    
}

把host作为参数传递的使用案例;

      host = createNode([0, 51, 0], [100, 100, 100]).s({  
                    'label': 'Cube',
                    'label.visible': false,
                    'all.image': 'dice',                    
                    'front.uv': [0.25, 0.75, 0.25, 1, 0.5, 1, 0.5, 0.75],                    
                    'back.uv': [0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.5, 0.25],
                    'bottom.uv': [0.25, 0, 0.25, 0.25, 0.5, 0.25, 0.5, 0],
                    'left.uv': [0, 0.75, 0, 1, 0.25, 1, 0.25, 0.75],
                    'right.uv': [0.5, 0.75, 0.5, 1, 0.75, 1, 0.75, 0.75],
                    'front.opacity': 0.5,
                    'front.transparent': true,                      
                    'front.blend': 'red',
                    'top.visible': false,                    
                    'all.reverse.flip': true,
                    'note': 'A good example about customizing uv',
                    'note.face': 'right',
                    'note.autorotate': true,
                    'note2': 'A fixed note',
                    'note2.face': 'front',                    
                    'note2.position': 6,
                    'icons': {
                        ICONS1: {
                            names: ['node_icon', 'group_icon', 'subGraph_icon', 'grid_icon', 'shape_icon', 'edge_icon'],                            
                            position: 5
                        },
                        ICONS2: {
                            names: ['earth', 'colors', 'fab', 'dice'],
                            position: 26,                            
                            width: 30,
                            height: 30,
                            gap: 5,                            
                            direction: 'north', 
                            face: 'left',
                            r3: [Math.PI/2, Math.PI/2, 0],
                            rotationMode: 'yxz',
                            t3: [-15, 15, 0]
                        }
                    }
                }); 

                createNode([0, 51, -50], [50, 50, 50], host).s({
                    'shape3d': 'sphere',
                    'shape3d.image': 'earth',
                    'body.color': 'red',
                    'label': 'Sphere',
                    'label.background': 'yellow',
                    'label2': 'Sphere',
                    'label2.background': 'blue',
                    'label2.position': 3,
                    'label2.face': 'back'
                });      




 function createNode(p3, s3, host){
                var node = new ht.Node();
                node.p3(p3);
                node.s3(s3);
                node.setHost(host);
                dataModel.add(node);
                return node;
            }         
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容

  • 《裕语言》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 10...
    叶染柒丶阅读 25,597评论 5 18
  • 1. 关于诊断X线机准直器的作用,错误的是()。 (6.0 分) A. 显示照射野 B. 显示中心线 C. 屏蔽多...
    我们村我最帅阅读 10,185评论 0 5
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,525评论 18 399
  • {1}消息 一般来说,把消息分为:好消息和坏消息。 在七月的最后一天,一个突如其来的坏消息。那天妹妹来我出租屋,我...
    之之了阅读 857评论 0 2
  • 我有二个女儿,一个快三岁,一个快一岁。二个女儿都很漂亮,而且聪明可人(估计所有的爸爸都会这样认为自己的女儿,呵呵)...
    4ccd352c5b0e阅读 602评论 3 3