
俗話說,有人的地方就有江湖,江湖就是幫派林立錯綜復雜的關系網。今天我們就來展示這樣一個小小的江湖。
故事背景
崇禎末年,民不聊生,烽煙四起……
江湖都是有背景的,我們的3D江湖也需要一個背景。江湖就是一個舞台,舞台就要有空間、場地、燈光和觀眾。在我們的3D舞台中,box就是空間,容納所有物體;network就是場地,展示千姿百態;PointLight和AmbientLight就是燈光,讓畫面更立體鮮亮;Camera就是觀眾,沒有觀眾戲就永遠不會開場。下面就看看這個江湖是個怎樣的背景:
var box = new mono.DataBox();
var network= new mono.Network3D(box, null, twaverCanvas);
mono.Utils.autoAdjustNetworkBounds(network,document.documentElement,'clientWidth','clientHeight');
network.getCamera().setPosition(-500, 800, 1900);
network.getCamera().setFov(30);
network.isSelectable=function(){return false};
network.setClearColor('black');
network.getDefaultInteraction().minDistance = 500;
network.getDefaultInteraction().maxDistance = 3000;
network.getDefaultInteraction().yLowerLimitAngle=0;
network.getDefaultInteraction().yUpLimitAngle=Math.PI/2;
var pointLight = new mono.PointLight(0xFFFFFF,0.5);
pointLight.setPosition(0,1000,0);
box.add(pointLight);
box.add(new mono.AmbientLight(0x888888));
江湖初現
現在,江湖已經在那里了,但我們卻什么都看不見。這是因為,里面還沒有任何我們能看到的東西。
好吧,為了讓這個江湖更像舞台,我們就真的搭建一個平台:
var ground=new mono.Cube(4200/2, 20, 3000/2);
ground.s({
'm.type': 'phong',
'm.color': '#f2f2f2',
'm.ambient': '#f2f2f2',
});
ground.setPositionY(-ground.getHeight()/2);
box.add(ground);

舞台已建好,接下來就該人物登場了。
大俠誕生
咱們創造是是一個高度意象的江湖,人物也是高度抽象的形象,所謂大象無形大音希聲,大家就體會個概念吧。
首先,讓我們看看大俠的頭部:
var head=new mono.Sphere(8, 10, 10);
head.s({
'm.color': '#F3E2A9',
'm.ambient': '#F3E2A9',
'm.type': 'phong',
});
head.setPositionY(38);
box.add(head);
什么?就是個圓球!
嗯哪。都說一百個人心中就有一百個什么那他,至於五官樣貌就全憑大家想象了。
接下來再看看大俠的身體:
var body=new mono.Sphere(11, 10, 10);
body.s({
'm.type': 'phong',
'm.texture.image': pic,
'm.texture.repeat': repeat ? repeat : new mono.Vec2(2,2),
});
body.setScaleY(1.6);
body.setPositionY(15);
box.add(body);
不出大家意料,是個橢球。不過再抽象,衣服還是要穿的,裸奔不是我俠的風范。

立錐之地
大俠已誕生,怎么也要給人家個勢力范圍啊。
var pad=new mono.Cylinder(20,20,2.5);
pad.s({
'm.color': '#F5F5F5',
'm.type': 'phong',
'top.m.lightmap.image': 'shadow.jpg',
});
還要稍微裝飾一下,給加個邊框:
var pad1=new mono.Cylinder(23,23,3,15);
pad1.s({
'm.color': '#2ECCFA',
'm.ambient': '#2ECCFA',
'm.type': 'phong',
});
var pad2=new mono.Cylinder(20,20,3,15);
pad2.s({
'm.color': '#2ECCFA',
'm.ambient': '#2ECCFA',
'm.type': 'phong',
});
var padEdge=new mono.ComboNode([pad1, pad2], ['-']);
box.add(padEdge);
為了將其變成大俠永遠的私有之地,還需要將他們結合到一起。
head.setParent(pad); body.setParent(pad); padEdge.setParent(pad); pad.setPosition(position);
初入江湖
大俠已出,終於可以闖江湖了!先來他50多個,來來來,排一排:
var user=createUser(box, new mono.Vec3(0,0,0), 'cloth.jpg');
var count=50;
for(var i=0;i<count;i++){
var x=500*Math.cos(Math.PI*2/count*i);
var z=500*Math.sin(Math.PI*2/count*i);
createUser(box, new mono.Vec3(x,0,z), 'cloth'+parseInt(Math.random()*3+1)+'.jpg');
}

不太壯觀啊,再來他400個!果然有了江湖的感覺。
for(var i=0;i<400;i++){
var x=Math.random()*Math.random()*ground.getWidth()/2;
x=Math.random()>0.5 ? x : -x;
var y=Math.random()*Math.random()*ground.getDepth()/2;
y=Math.random()>0.5 ? y : -y;
createUser(box, new mono.Vec3(x, 0, y), 'cloth'+parseInt(Math.random()*3+1)+'.jpg');
}

人在江湖
江湖險惡,哪里是只憑衣服就分出了幫派,必須是你中有我我中有你錯綜復雜恩怨情仇各種明爭暗斗,這些復雜的關系就需要用各種連線標識一下了。
function createLine(box, x1, z1, x2, z2, color){
color=color || '#2ECCFA';
var path = new mono.Path();
path.moveTo(x1, z1,0);
path.lineTo((x1+x2)/2+100, (z1+z2)/2+100, 0);
path.lineTo(x2, z2, 0);
path=mono.PathNode.prototype.adjustPath(path, 50);
var line=new mono.PathCube(path, 3, 1, 10);
line.s({
'm.color': color,
'm.ambient': color,
'm.type': 'phong',
});
box.add(line);
}
通過給出不同點和顏色,就可以形成各種連線。
對於最初的51人,我們簡單的將周邊與圓心連接,體現出一個強有力的領導核心。
后來的400人,每10人添加一根連線——當然按說應該是每人都有多根連線才真實,但那就滿屏全是線沒法看了。

一個小小的江湖,就這樣形成了!你有沒有感受到江湖的魔力和魅力呢?
江湖啟示
其實,我們都身在江湖,要想安身立命,不能只靠江湖義氣,真才實學才是闖盪江湖的本錢!
從這個實例中,我們應該學到在立體拓撲圖中,借鑒平面拓撲布局的一種方法,提供的是一種在立體圖形中展示平面拓撲的思路。其實類似的應用場景很多,大家稍做變換就可以打造適合自己的特色3D拓撲圖了。
正看文章的小哥,我看你骨骼精奇,是個練武的奇才!我這里有一部TWaver3D寶典,何不入我賽瓦門,咱們一起闖盪江湖!
