# 節(jié)點
元素雖然有很多派生,但本質(zhì)上可以分為兩類——3D節(jié)點和非3D節(jié)點(簡稱節(jié)點)。節(jié)點Node對應(yīng)的標(biāo)簽是xr-node,它是場景中用于渲染的元素的基礎(chǔ),本質(zhì)上是在基礎(chǔ)元素的基礎(chǔ)上默認(rèn)添加了Transform變換組件。
# 變換組件
變換組件提供了渲染最基礎(chǔ)的位置position、旋轉(zhuǎn)rotation和縮放scale能力,原理上來講,整個3D場景的渲染就是由很多個變換組件的級聯(lián)實現(xiàn)的,最終構(gòu)成一顆場景節(jié)點樹。
要使用變換組件,我們有兩種方式,一種是直接作為組件使用:
<xr-element transform="position: 1 1 1;nodeId=node1">
<xr-element transform="position: 1 2 1"></xr-element>
</xr-element>
這個例子中,我們創(chuàng)建了兩個帶有變換組件的元素,并將它們級聯(lián)了起來。而通過使用節(jié)點元素,我們可以將其等價地寫成:
<xr-node node-id="node1" position="1 1 1">
<xr-node position="1 2 1"></xr-node>
</xr-node>
可見,節(jié)點元素其實就是將變換組件的屬性做了一下映射。我們還可以注意到nodeId這個數(shù)據(jù),它和元素的id不同,是專門給變換組件用的一個索引。在組件數(shù)據(jù)解析一章最后,有一種transform類型的內(nèi)置數(shù)據(jù)類型的值,就是這個nodeId。此外,我們還可用以下方法來手動獲取變換組件的引用:
const trs = scene.getNodeById(nodeId);
// 修改位置
trs.position.x = 10;
trs.position.setValue(10, 10, 10);
trs.position.setFromArray([1, 1, 1]);
trs.position.set(new xrFrameSystem.Vector3());
// 歐拉角、縮放、四元素也是類似的
trs.rotation.y = 10;
trs.scale.z = 2;
trs.quaternion.w = 1;
更多屬性請看API文檔。
# 派生
節(jié)點作為一類特殊的元素的基礎(chǔ),很多元素都是派生自它的,比如燈光、相機(jī)等等,所以它的默認(rèn)組件集和數(shù)據(jù)映射表非常常見,一般來講要派生自節(jié)點,我們需要這么做:
import XrFrame from 'XrFrame';
const xrFrameSystem = wx.getXrFrameSystem();
const CustomDefaultComponents: XrFrame.IEntityComponents = Object.assign({
'custom-component': {
customData: value
}
}, xrFrameSystem.NodeDefaultComponents);
const CustomStarDataMapping: {[key: string]: string[];} = Object.assign({
'custom-data': ['custom-component', 'customData']
}, xrFrameSystem.NodeDataMapping);
xrFrameSystem.registerElement('custom', class XRCustom extends xrFrameSystem.Element {
public readonly defaultComponents: XrFrame.IEntityComponents = CustomStarDefaultComponents;
public readonly dataMapping: {[key: string]: string[];} = CustomStarDataMapping;
});
關(guān)鍵在于對xrFrameSystem.NodeDefaultComponents和xrFrameSystem.NodeDataMapping的合并。
# 可見性與圖層
對于節(jié)點和派生自節(jié)點的元素(也就是掛載了Transform組件的元素),都有visible和layer兩個屬性可選。這兩個屬性用于控制節(jié)點自身以及其子孫結(jié)點的可見性。
當(dāng)我們需要需要一個開關(guān)直截了當(dāng)?shù)米屇硞€節(jié)點之下的所有模型或者燈光都顯示或者不顯示,最方便的方法就是使用visible:
<xr-node visible="false">
<xr-mesh visible geometry="cube" />
</xr-node>
比如這個例子,所有節(jié)點的visible默認(rèn)都是true,但當(dāng)父節(jié)點設(shè)置為false時,即便子節(jié)點顯式定義了true,也會被隱藏。
除了這種場景,在另外一些場景我們還會有更復(fù)雜的需求,比如只是想針對性得剔除掉某一類模型或是燈光,而非按照層級結(jié)構(gòu),這時候圖層layer就派上用場了,讓我么來看個例子:
<xr-node layer="1">
<xr-mesh geometry="sphere" uniforms="u_baseColorFactor:0.937 0.176 0.368 1" />
<xr-node layer="2">
<xr-mesh geometry="cylinder" uniforms="u_baseColorFactor:1 0.776 0.364 1" />
</xr-node>
</xr-node>
<xr-camera
position="0 1.6 0" clear-color="0.925 0.925 0.925 1"
cull-mask="0b01"
/>
對于兩個xr-node節(jié)點,我們給第一層指定了layer=1,第二層指定了layer=2,然后將xr-camere節(jié)點的cull-mask屬性(對應(yīng)于Camera組件的cullMask數(shù)據(jù))設(shè)置為0b01。如此設(shè)置的效果應(yīng)該是第一個mesh被渲染,第二個不被渲染。
開發(fā)者看到這里應(yīng)該不難發(fā)現(xiàn)圖層的規(guī)則:layer可以設(shè)置1~32共32個值,而相機(jī)的cullMask是一個32位無符號整數(shù),每一位都代表一個layer。只有當(dāng)一個節(jié)點從頂層到自身路徑中的所有節(jié)點都通過了這個mask的測試,才會被顯示出來。這也適用于燈光Light組件。