123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta name="generator" content="Asciidoctor 1.5.4">
- <meta name="keywords" content="spatial, node, mesh, geometry, scenegraph">
- <title>Spatial</title>
- <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
- <style>
- /* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
- /* Remove comment around @import statement below when using as a custom stylesheet */
- /*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700";*/
- article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
- audio,canvas,video{display:inline-block}
- audio:not([controls]){display:none;height:0}
- [hidden],template{display:none}
- script{display:none!important}
- html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}
- body{margin:0}
- a{background:transparent}
- a:focus{outline:thin dotted}
- a:active,a:hover{outline:0}
- h1{font-size:2em;margin:.67em 0}
- abbr[title]{border-bottom:1px dotted}
- b,strong{font-weight:bold}
- dfn{font-style:italic}
- hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}
- mark{background:#ff0;color:#000}
- code,kbd,pre,samp{font-family:monospace;font-size:1em}
- pre{white-space:pre-wrap}
- q{quotes:"\201C" "\201D" "\2018" "\2019"}
- small{font-size:80%}
- sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}
- sup{top:-.5em}
- sub{bottom:-.25em}
- img{border:0}
- svg:not(:root){overflow:hidden}
- figure{margin:0}
- fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}
- legend{border:0;padding:0}
- button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}
- button,input{line-height:normal}
- button,select{text-transform:none}
- button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}
- button[disabled],html input[disabled]{cursor:default}
- input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}
- input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}
- input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}
- button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
- textarea{overflow:auto;vertical-align:top}
- table{border-collapse:collapse;border-spacing:0}
- *,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}
- html,body{font-size:100%}
- body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto}
- a:hover{cursor:pointer}
- img,object,embed{max-width:100%;height:auto}
- object,embed{height:100%}
- img{-ms-interpolation-mode:bicubic}
- .left{float:left!important}
- .right{float:right!important}
- .text-left{text-align:left!important}
- .text-right{text-align:right!important}
- .text-center{text-align:center!important}
- .text-justify{text-align:justify!important}
- .hide{display:none}
- body{-webkit-font-smoothing:antialiased}
- img,object,svg{display:inline-block;vertical-align:middle}
- textarea{height:auto;min-height:50px}
- select{width:100%}
- .center{margin-left:auto;margin-right:auto}
- .spread{width:100%}
- p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6}
- .subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em}
- div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr}
- a{color:#2156a5;text-decoration:underline;line-height:inherit}
- a:hover,a:focus{color:#1d4b8f}
- a img{border:none}
- p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility}
- p aside{font-size:.875em;line-height:1.35;font-style:italic}
- h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em}
- h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0}
- h1{font-size:2.125em}
- h2{font-size:1.6875em}
- h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em}
- h4,h5{font-size:1.125em}
- h6{font-size:1em}
- hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0}
- em,i{font-style:italic;line-height:inherit}
- strong,b{font-weight:bold;line-height:inherit}
- small{font-size:60%;line-height:inherit}
- code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)}
- ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
- ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em}
- ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em}
- ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
- ul.square{list-style-type:square}
- ul.circle{list-style-type:circle}
- ul.disc{list-style-type:disc}
- ul.no-bullet{list-style:none}
- ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
- dl dt{margin-bottom:.3125em;font-weight:bold}
- dl dd{margin-bottom:1.25em}
- abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help}
- abbr{text-transform:none}
- blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd}
- blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)}
- blockquote cite:before{content:"\2014 \0020"}
- blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)}
- blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)}
- @media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2}
- h1{font-size:2.75em}
- h2{font-size:2.3125em}
- h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em}
- h4{font-size:1.4375em}}
- table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede}
- table thead,table tfoot{background:#f7f8f7;font-weight:bold}
- table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left}
- table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)}
- table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7}
- table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6}
- body{tab-size:4}
- h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em}
- h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400}
- .clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table}
- .clearfix:after,.float-group:after{clear:both}
- *:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
- pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed}
- .keyseq{color:rgba(51,51,51,.8)}
- kbd{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;display:inline-block;color:rgba(0,0,0,.8);font-size:.65em;line-height:1.45;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:0 .15em;padding:.2em .5em;vertical-align:middle;position:relative;top:-.1em;white-space:nowrap}
- .keyseq kbd:first-child{margin-left:0}
- .keyseq kbd:last-child{margin-right:0}
- .menuseq,.menu{color:rgba(0,0,0,.8)}
- b.button:before,b.button:after{position:relative;top:-1px;font-weight:400}
- b.button:before{content:"[";padding:0 3px 0 2px}
- b.button:after{content:"]";padding:0 2px 0 3px}
- p a>code:hover{color:rgba(0,0,0,.9)}
- #header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em}
- #header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table}
- #header:after,#content:after,#footnotes:after,#footer:after{clear:both}
- #content{margin-top:1.25em}
- #content:before{content:none}
- #header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
- #header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8}
- #header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px}
- #header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap}
- #header .details span:first-child{margin-left:-.125em}
- #header .details span.email a{color:rgba(0,0,0,.85)}
- #header .details br{display:none}
- #header .details br+span:before{content:"\00a0\2013\00a0"}
- #header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)}
- #header .details br+span#revremark:before{content:"\00a0|\00a0"}
- #header #revnumber{text-transform:capitalize}
- #header #revnumber:after{content:"\00a0"}
- #content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem}
- #toc{border-bottom:1px solid #efefed;padding-bottom:.5em}
- #toc>ul{margin-left:.125em}
- #toc ul.sectlevel0>li>a{font-style:italic}
- #toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0}
- #toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none}
- #toc li{line-height:1.3334;margin-top:.3334em}
- #toc a{text-decoration:none}
- #toc a:active{text-decoration:underline}
- #toctitle{color:#7a2518;font-size:1.2em}
- @media only screen and (min-width:768px){#toctitle{font-size:1.375em}
- body.toc2{padding-left:15em;padding-right:0}
- #toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
- #toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
- #toc.toc2>ul{font-size:.9em;margin-bottom:0}
- #toc.toc2 ul ul{margin-left:0;padding-left:1em}
- #toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em}
- body.toc2.toc-right{padding-left:0;padding-right:15em}
- body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}
- @media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0}
- #toc.toc2{width:20em}
- #toc.toc2 #toctitle{font-size:1.375em}
- #toc.toc2>ul{font-size:.95em}
- #toc.toc2 ul ul{padding-left:1.25em}
- body.toc2.toc-right{padding-left:0;padding-right:20em}}
- #content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
- #content #toc>:first-child{margin-top:0}
- #content #toc>:last-child{margin-bottom:0}
- #footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em}
- #footer-text{color:rgba(255,255,255,.8);line-height:1.44}
- .sect1{padding-bottom:.625em}
- @media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}
- .sect1+.sect1{border-top:1px solid #efefed}
- #content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400}
- #content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em}
- #content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible}
- #content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none}
- #content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221}
- .audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em}
- .admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic}
- table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0}
- .paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)}
- table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit}
- .admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%}
- .admonitionblock>table td.icon{text-align:center;width:80px}
- .admonitionblock>table td.icon img{max-width:none}
- .admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase}
- .admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)}
- .admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
- .exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px}
- .exampleblock>.content>:first-child{margin-top:0}
- .exampleblock>.content>:last-child{margin-bottom:0}
- .sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px}
- .sidebarblock>:first-child{margin-top:0}
- .sidebarblock>:last-child{margin-bottom:0}
- .sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
- .exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
- .literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8}
- .sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1}
- .literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em}
- .literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal}
- @media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}
- @media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}
- .literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)}
- .listingblock pre.highlightjs{padding:0}
- .listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px}
- .listingblock pre.prettyprint{border-width:0}
- .listingblock>.content{position:relative}
- .listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999}
- .listingblock:hover code[data-lang]:before{display:block}
- .listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999}
- .listingblock.terminal pre .command:not([data-prompt]):before{content:"$"}
- table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none}
- table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0;line-height:1.45}
- table.pyhltable td.code{padding-left:.75em;padding-right:0}
- pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8}
- pre.pygments .lineno{display:inline-block;margin-right:.25em}
- table.pyhltable .linenodiv{background:none!important;padding-right:0!important}
- .quoteblock{margin:0 1em 1.25em 1.5em;display:table}
- .quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em}
- .quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify}
- .quoteblock blockquote{margin:0;padding:0;border:0}
- .quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)}
- .quoteblock blockquote>.paragraph:last-child p{margin-bottom:0}
- .quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right}
- .quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)}
- .quoteblock .quoteblock blockquote{padding:0 0 0 .75em}
- .quoteblock .quoteblock blockquote:before{display:none}
- .verseblock{margin:0 1em 1.25em 1em}
- .verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility}
- .verseblock pre strong{font-weight:400}
- .verseblock .attribution{margin-top:1.25rem;margin-left:.5ex}
- .quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic}
- .quoteblock .attribution br,.verseblock .attribution br{display:none}
- .quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.025em;color:rgba(0,0,0,.6)}
- .quoteblock.abstract{margin:0 0 1.25em 0;display:block}
- .quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0}
- .quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none}
- table.tableblock{max-width:100%;border-collapse:separate}
- table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0}
- table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede}
- table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0}
- table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0}
- table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0}
- table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0}
- table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0}
- table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0}
- table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0}
- table.frame-all{border-width:1px}
- table.frame-sides{border-width:0 1px}
- table.frame-topbot{border-width:1px 0}
- th.halign-left,td.halign-left{text-align:left}
- th.halign-right,td.halign-right{text-align:right}
- th.halign-center,td.halign-center{text-align:center}
- th.valign-top,td.valign-top{vertical-align:top}
- th.valign-bottom,td.valign-bottom{vertical-align:bottom}
- th.valign-middle,td.valign-middle{vertical-align:middle}
- table thead th,table tfoot th{font-weight:bold}
- tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7}
- tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold}
- p.tableblock>code:only-child{background:none;padding:0}
- p.tableblock{font-size:1em}
- td>div.verse{white-space:pre}
- ol{margin-left:1.75em}
- ul li ol{margin-left:1.5em}
- dl dd{margin-left:1.125em}
- dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0}
- ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em}
- ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none}
- ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em}
- ul.checklist li>p:first-child>.fa-square-o:first-child,ul.checklist li>p:first-child>.fa-check-square-o:first-child{width:1em;font-size:.85em}
- ul.checklist li>p:first-child>input[type="checkbox"]:first-child{width:1em;position:relative;top:1px}
- ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden}
- ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block}
- ul.inline>li>*{display:block}
- .unstyled dl dt{font-weight:400;font-style:normal}
- ol.arabic{list-style-type:decimal}
- ol.decimal{list-style-type:decimal-leading-zero}
- ol.loweralpha{list-style-type:lower-alpha}
- ol.upperalpha{list-style-type:upper-alpha}
- ol.lowerroman{list-style-type:lower-roman}
- ol.upperroman{list-style-type:upper-roman}
- ol.lowergreek{list-style-type:lower-greek}
- .hdlist>table,.colist>table{border:0;background:none}
- .hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none}
- td.hdlist1,td.hdlist2{vertical-align:top;padding:0 .625em}
- td.hdlist1{font-weight:bold;padding-bottom:1.25em}
- .literalblock+.colist,.listingblock+.colist{margin-top:-.5em}
- .colist>table tr>td:first-of-type{padding:0 .75em;line-height:1}
- .colist>table tr>td:last-of-type{padding:.25em 0}
- .thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd}
- .imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0}
- .imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em}
- .imageblock>.title{margin-bottom:0}
- .imageblock.thumb,.imageblock.th{border-width:6px}
- .imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em}
- .image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0}
- .image.left{margin-right:.625em}
- .image.right{margin-left:.625em}
- a.image{text-decoration:none;display:inline-block}
- a.image object{pointer-events:none}
- sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
- sup.footnote a,sup.footnoteref a{text-decoration:none}
- sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
- #footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
- #footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0}
- #footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;text-indent:-1.05em;margin-bottom:.2em}
- #footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none}
- #footnotes .footnote:last-of-type{margin-bottom:0}
- #content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0}
- .gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0}
- .gist .file-data>table td.line-data{width:99%}
- div.unbreakable{page-break-inside:avoid}
- .big{font-size:larger}
- .small{font-size:smaller}
- .underline{text-decoration:underline}
- .overline{text-decoration:overline}
- .line-through{text-decoration:line-through}
- .aqua{color:#00bfbf}
- .aqua-background{background-color:#00fafa}
- .black{color:#000}
- .black-background{background-color:#000}
- .blue{color:#0000bf}
- .blue-background{background-color:#0000fa}
- .fuchsia{color:#bf00bf}
- .fuchsia-background{background-color:#fa00fa}
- .gray{color:#606060}
- .gray-background{background-color:#7d7d7d}
- .green{color:#006000}
- .green-background{background-color:#007d00}
- .lime{color:#00bf00}
- .lime-background{background-color:#00fa00}
- .maroon{color:#600000}
- .maroon-background{background-color:#7d0000}
- .navy{color:#000060}
- .navy-background{background-color:#00007d}
- .olive{color:#606000}
- .olive-background{background-color:#7d7d00}
- .purple{color:#600060}
- .purple-background{background-color:#7d007d}
- .red{color:#bf0000}
- .red-background{background-color:#fa0000}
- .silver{color:#909090}
- .silver-background{background-color:#bcbcbc}
- .teal{color:#006060}
- .teal-background{background-color:#007d7d}
- .white{color:#bfbfbf}
- .white-background{background-color:#fafafa}
- .yellow{color:#bfbf00}
- .yellow-background{background-color:#fafa00}
- span.icon>.fa{cursor:default}
- .admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default}
- .admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c}
- .admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111}
- .admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900}
- .admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400}
- .admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000}
- .conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold}
- .conum[data-value] *{color:#fff!important}
- .conum[data-value]+b{display:none}
- .conum[data-value]:after{content:attr(data-value)}
- pre .conum[data-value]{position:relative;top:-.125em}
- b.conum *{color:inherit!important}
- .conum:not([data-value]):empty{display:none}
- dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
- h1,h2,p,td.content,span.alt{letter-spacing:-.01em}
- p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
- p,blockquote,dt,td.content,span.alt{font-size:1.0625rem}
- p{margin-bottom:1.25rem}
- .sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
- .exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc}
- .print-only{display:none!important}
- @media print{@page{margin:1.25cm .75cm}
- *{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important}
- a{color:inherit!important;text-decoration:underline!important}
- a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important}
- a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em}
- abbr[title]:after{content:" (" attr(title) ")"}
- pre,blockquote,tr,img,object,svg{page-break-inside:avoid}
- thead{display:table-header-group}
- svg{max-width:100%}
- p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3}
- h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid}
- #toc,.sidebarblock,.exampleblock>.content{background:none!important}
- #toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important}
- .sect1{padding-bottom:0!important}
- .sect1+.sect1{border:0!important}
- #header>h1:first-child{margin-top:1.25rem}
- body.book #header{text-align:center}
- body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0}
- body.book #header .details{border:0!important;display:block;padding:0!important}
- body.book #header .details span:first-child{margin-left:0!important}
- body.book #header .details br{display:block}
- body.book #header .details br+span:before{content:none!important}
- body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important}
- body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always}
- .listingblock code[data-lang]:before{display:block}
- #footer{background:none!important;padding:0 .9375em}
- #footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em}
- .hide-on-print{display:none!important}
- .print-only{display:block!important}
- .hide-for-print{display:none!important}
- .show-for-print{display:inherit!important}}
- </style>
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css">
- <style>
- /* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
- /*pre.CodeRay {background-color:#f7f7f8;}*/
- .CodeRay .line-numbers{border-right:1px solid #d8d8d8;padding:0 0.5em 0 .25em}
- .CodeRay span.line-numbers{display:inline-block;margin-right:.5em;color:rgba(0,0,0,.3)}
- .CodeRay .line-numbers strong{color:rgba(0,0,0,.4)}
- table.CodeRay{border-collapse:separate;border-spacing:0;margin-bottom:0;border:0;background:none}
- table.CodeRay td{vertical-align: top;line-height:1.45}
- table.CodeRay td.line-numbers{text-align:right}
- table.CodeRay td.line-numbers>pre{padding:0;color:rgba(0,0,0,.3)}
- table.CodeRay td.code{padding:0 0 0 .5em}
- table.CodeRay td.code>pre{padding:0}
- .CodeRay .debug{color:#fff !important;background:#000080 !important}
- .CodeRay .annotation{color:#007}
- .CodeRay .attribute-name{color:#000080}
- .CodeRay .attribute-value{color:#700}
- .CodeRay .binary{color:#509}
- .CodeRay .comment{color:#998;font-style:italic}
- .CodeRay .char{color:#04d}
- .CodeRay .char .content{color:#04d}
- .CodeRay .char .delimiter{color:#039}
- .CodeRay .class{color:#458;font-weight:bold}
- .CodeRay .complex{color:#a08}
- .CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
- .CodeRay .color{color:#099}
- .CodeRay .class-variable{color:#369}
- .CodeRay .decorator{color:#b0b}
- .CodeRay .definition{color:#099}
- .CodeRay .delimiter{color:#000}
- .CodeRay .doc{color:#970}
- .CodeRay .doctype{color:#34b}
- .CodeRay .doc-string{color:#d42}
- .CodeRay .escape{color:#666}
- .CodeRay .entity{color:#800}
- .CodeRay .error{color:#808}
- .CodeRay .exception{color:inherit}
- .CodeRay .filename{color:#099}
- .CodeRay .function{color:#900;font-weight:bold}
- .CodeRay .global-variable{color:#008080}
- .CodeRay .hex{color:#058}
- .CodeRay .integer,.CodeRay .float{color:#099}
- .CodeRay .include{color:#555}
- .CodeRay .inline{color:#000}
- .CodeRay .inline .inline{background:#ccc}
- .CodeRay .inline .inline .inline{background:#bbb}
- .CodeRay .inline .inline-delimiter{color:#d14}
- .CodeRay .inline-delimiter{color:#d14}
- .CodeRay .important{color:#555;font-weight:bold}
- .CodeRay .interpreted{color:#b2b}
- .CodeRay .instance-variable{color:#008080}
- .CodeRay .label{color:#970}
- .CodeRay .local-variable{color:#963}
- .CodeRay .octal{color:#40e}
- .CodeRay .predefined{color:#369}
- .CodeRay .preprocessor{color:#579}
- .CodeRay .pseudo-class{color:#555}
- .CodeRay .directive{font-weight:bold}
- .CodeRay .type{font-weight:bold}
- .CodeRay .predefined-type{color:inherit}
- .CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
- .CodeRay .key{color:#808}
- .CodeRay .key .delimiter{color:#606}
- .CodeRay .key .char{color:#80f}
- .CodeRay .value{color:#088}
- .CodeRay .regexp .delimiter{color:#808}
- .CodeRay .regexp .content{color:#808}
- .CodeRay .regexp .modifier{color:#808}
- .CodeRay .regexp .char{color:#d14}
- .CodeRay .regexp .function{color:#404;font-weight:bold}
- .CodeRay .string{color:#d20}
- .CodeRay .string .string .string{background:#ffd0d0}
- .CodeRay .string .content{color:#d14}
- .CodeRay .string .char{color:#d14}
- .CodeRay .string .delimiter{color:#d14}
- .CodeRay .shell{color:#d14}
- .CodeRay .shell .delimiter{color:#d14}
- .CodeRay .symbol{color:#990073}
- .CodeRay .symbol .content{color:#a60}
- .CodeRay .symbol .delimiter{color:#630}
- .CodeRay .tag{color:#008080}
- .CodeRay .tag-special{color:#d70}
- .CodeRay .variable{color:#036}
- .CodeRay .insert{background:#afa}
- .CodeRay .delete{background:#faa}
- .CodeRay .change{color:#aaf;background:#007}
- .CodeRay .head{color:#f8f;background:#505}
- .CodeRay .insert .insert{color:#080}
- .CodeRay .delete .delete{color:#800}
- .CodeRay .change .change{color:#66f}
- .CodeRay .head .head{color:#f4f}
- </style>
- </head>
- <body class="article toc2 toc-left">
- <div id="header">
- <h1>Spatial</h1>
- <div class="details">
- <span id="author" class="author"></span><br>
- <span id="revnumber">version ,</span>
- <span id="revdate">2016/03/17 20:48</span>
- </div>
- <div id="toc" class="toc2">
- <div id="toctitle">Table of Contents</div>
- <ul class="sectlevel1">
- <li><a href="#node-versus-geometry">Node versus Geometry</a>
- <ul class="sectlevel2">
- <li><a href="#mesh">Mesh</a></li>
- </ul>
- </li>
- <li><a href="#what-is-a-clone">What is a Clone?</a></li>
- <li><a href="#how-to-add-fields-and-methods-to-a-spatial">How to Add Fields and Methods to a Spatial</a></li>
- <li><a href="#how-to-access-a-named-sub-mesh">How to Access a Named Sub-Mesh</a></li>
- <li><a href="#what-is-culling">What is Culling?</a></li>
- <li><a href="#see-also">See also</a></li>
- </ul>
- </div>
- </div>
- <div id="content">
- <div id="preamble">
- <div class="sectionbody">
- <div class="paragraph">
- <p>This is an introduction to the concept of Spatials, the elements of the 3D scene graph. The scene graph is a data structure that manages all objects in your 3D world. For example, the scene graph keeps track of the 3D models that you load and position. When you extend a Java class from com.jme3.app.SimpleApplication, you automatically inherit the scene graph and its rootNode.</p>
- </div>
- <div class="paragraph">
- <p>The rootNode is the central element of the scene graph. Even if the scene graph is empty, it always contains at least the rootNode. We <em>attach</em> Spatials to the rootNode. Attached Spatials are always in a <em>parent-child relationship</em>. Every time you attach a Spatial to something, it is implicitly detached from its previous parent. A Spatial can have only one parent. A Spatial can have several children.</p>
- </div>
- <div class="paragraph">
- <p>If you think you need to understand the scene graph concept better, please read <a href="../../jme3/scenegraph_for_dummies.html">Scenegraph for dummies</a> first.</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="node-versus-geometry">Node versus Geometry</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>In your Java code, a Spatial is either an instance of <code>com.jme3.scene.Node</code> or a <code>com.jme3.scene.Geometry</code> instance. You use the two types of Spatials for different purposes:</p>
- </div>
- <div class="imageblock" style="text-align: center">
- <div class="content">
- <img src="../../jme3/intermediate/scene-graph.png" alt="scene-graph.png" height="">
- </div>
- </div>
- <table class="tableblock frame-all grid-all spread">
- <colgroup>
- <col style="width: 33.3333%;">
- <col style="width: 33.3333%;">
- <col style="width: 33.3334%;">
- </colgroup>
- <thead>
- <tr>
- <th class="tableblock halign-left valign-top"></th>
- <th class="tableblock halign-left valign-top" colspan="2">com.jme3.scene.Spatial</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Purpose:</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top" colspan="2"><div><div class="paragraph">
- <p>A Spatial is an abstract data structure that stores user data and transformations (= translation, rotation, scale) of elements of the 3D scene graph. Spatials can be saved and loaded using the <a href="../../jme3/advanced/asset_manager.html">Asset Manager</a>.</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>com.jme3.scene.Geometry</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>com.jme3.scene.Node</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Visibility:</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>A Geometry represents a <strong>visible</strong> 3D object in the scene graph.</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>A Node is an <strong>invisible “handle</strong> for a group of Spatials in the scene graph.</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Purpose:</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Use Geometries to represent an object’s <strong>look</strong>: Every Geometry contains a polygon mesh and a material, specifying its shape, color, texture, and opacity/transparency.<br>
- You attach Geometries to Nodes.</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Use Nodes to <strong>structure and group</strong> Geometries and other Nodes. Every Node is attached to one parent node, and each node can have zero or more children (Nodes or Geometries) attached to itself.<br>
- <strong>When you transform (move, rotate, etc) a parent node, all its children are transformed (moved, rotated, etc).</strong></p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Content:</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Transformations; custom user data;<br>
- mesh and material;</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Transformations; custom user data;<br>
- no mesh, no material.</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Examples:</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>Box, sphere, player, building, terrain, vehicle, missiles, NPCs, etc…</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div><div class="paragraph">
- <p>rootNode, guiNode, audioNode, a custom grouping node such as vehicleNode or shipNode with passengers attached, etc.</p>
- </div></div></td>
- </tr>
- </tbody>
- </table>
- <div class="paragraph">
- <p><code><strike>Spatial s = new Spatial();</strike></code>“`Spatial`<em>cast</em></p>
- </div>
- <div class="sect2">
- <h3 id="mesh">Mesh</h3>
- <div class="paragraph">
- <p>The polygon <a href="../../jme3/advanced/mesh.html">Mesh</a> inside a Geometry can be one of three things:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p><strong>Shapes:</strong> The simplest type of Meshes are jME’s default <a href="../../jme3/advanced/shape.html">Shape</a>s such as cubes and spheres. You can use several Shapes to build complex Geometries. Shapes are built-in and can be created without using the AssetManager.</p>
- </li>
- <li>
- <p><strong>3D Models:</strong> <a href="../../jme3/advanced/3d_models.html">3D models and scenes</a> are also made up of meshes, but are more complex than Shapes. You create Models and Scenes in external 3D Mesh Editors and export them as Ogre XML or Wavefront OBJ. Use the <a href="../../jme3/advanced/asset_manager.html">Asset Manager</a> to load models into a your jME3 game.</p>
- </li>
- <li>
- <p><strong>Custom Meshes:</strong> Advanced users can create <a href="../../jme3/advanced/custom_meshes.html">Custom Meshes</a> programmatically.</p>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="what-is-a-clone">What is a Clone?</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>Cloned spatials share the same mesh, while each cloned spatial can have its own local transformation (translation, rotation, and scale) in the scene. This means you only use <code>clone()</code> on spatials whose meshes never change. The most common use case for cloning is when you use several Spatials that are based on the same <a href="../../jme3/advanced/shape.html">Shape</a>s (e.g. trees, crates).</p>
- </div>
- <div class="paragraph">
- <p>The second use case is: When you load a model using <code>loadModel()</code> from the AssetManager, you may automatically get a `clone()`ed object. In particular:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>If the model is not animated (it has no <code><a href="../../jme3/advanced/animation.html">AnimControl</a></code>), jME loads a clone. All clones share one mesh object in order to use less memory.</p>
- </li>
- <li>
- <p>If the model is animated (it has a <code><a href="../../jme3/advanced/animation.html">AnimControl</a></code>), then <code>loadModel()</code> duplicates the mesh for each loaded instance. (Uses more memory, but can animate.)</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>Usually there is no need to manually use any of the <code>clone()</code> methods on models. Using the <a href="../../jme3/advanced/asset_manager.html">Asset Manager</a>'s <code>loadModel()</code> method will automatically do the right thing for your models.</p>
- </div>
- <div class="paragraph">
- <p>“`Box()`<em>voxelization</em></p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="how-to-add-fields-and-methods-to-a-spatial">How to Add Fields and Methods to a Spatial</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>You can include custom user data –that is, custom Java objects and methods– in Nodes and Geometries. This is very useful for maintaining information about a game element, such as health, budget, ammunition, inventory, equipment, etc for players, or landmark locations for terrains, and much more.</p>
- </div>
- <div class="paragraph">
- <p><code>Node<code>Geometry</code><a href="../../jme3/advanced/custom_controls.html">Custom Controls</a>`Node</code>Geometry``setUserData()`</p>
- </div>
- <div class="paragraph">
- <p>This first example adds an integer field named <code>health</code> to the Spatial <code>playerNode</code>, and initializes it to 100.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java">playerNode.setUserData(<span class="string"><span class="delimiter">"</span><span class="content">health</span><span class="delimiter">"</span></span>, <span class="integer">100</span>);</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>The second example adds a set of custom accessor methods to the player object. You create a <a href="../../jme3/advanced/custom_controls.html">custom PlayerControl() class</a> and you add this control to the Spatial:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java">playerNode.addControl(<span class="keyword">new</span> PlayerControl());</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>In your PlayerControl() class, you define custom methods that set and get your user data in the <code>spatial</code> object. For example, the control could add accessors that set and get the player’s health:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">int</span> getHealth() {
- <span class="keyword">return</span> (<span class="predefined-type">Integer</span>)spatial.getUserData(<span class="string"><span class="delimiter">"</span><span class="content">health</span><span class="delimiter">"</span></span>);
- }
- <span class="directive">public</span> <span class="type">void</span> setHealth(<span class="type">int</span> h) {
- spatial.setUserData(<span class="string"><span class="delimiter">"</span><span class="content">health</span><span class="delimiter">"</span></span>,h);
- }</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>Elsewhere in your code, you can access this data wherever you have access to the Spatial <code>playerNode</code>.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java">health = playerNode.getControl(PlayerControl.class).getHealth();
- ...
- playerNode.getControl(PlayerControl.class).setHealth(<span class="integer">99</span>);</code></pre>
- </div>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>You can add as many data objects (of String, Boolean, Integer, Float, Array types) to a Spatial as you want. Just make sure to label them with unique case-sensitive strings (<code>health</code>, <code>Inventory</code>, <code>equipment</code>, etc).</p>
- </li>
- <li>
- <p>The saved data can even be a custom Java object if you make the custom Java class <a href="../../jme3/advanced/save_and_load.html#custom_savable_class">implement the Savable interface</a>!</p>
- </li>
- <li>
- <p>When you save a Spatial as a .j3o file, the custom data is saved, too, and all Savables are restored the next time you load the .j3o!</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>This is how you list all data keys that are already defined for one Spatial:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"><span class="keyword">for</span>(<span class="predefined-type">String</span> key : spatial.getUserDataKeys()){
- <span class="predefined-type">System</span>.out.println(spatial.getName()+<span class="string"><span class="delimiter">"</span><span class="content">'s keys: </span><span class="delimiter">"</span></span>+key);
- }</code></pre>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="how-to-access-a-named-sub-mesh">How to Access a Named Sub-Mesh</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>Often after you load a scene or model, you need to access a part of it as an individual Geometry in the scene graph. Maybe you want to swap a character’s weapon, or you want to play a door-opening animation. First you need to know the unique name of the sub-mesh.</p>
- </div>
- <div class="olist arabic">
- <ol class="arabic">
- <li>
- <p>Open the model in a 3D mesh editor, or in the jMonkeyEngine SDK’s Scene Composer.</p>
- </li>
- <li>
- <p>Find out the existing names of sub-meshes in the model.</p>
- </li>
- <li>
- <p>Assign unique names to sub-meshes in the model if neccessary.</p>
- </li>
- </ol>
- </div>
- <div class="paragraph">
- <p>In the following example, the Node <code>house</code> is the loaded model. The sub-meshes in the Node are called its children. The String, here <code>door 12</code>, is the name of the mesh that you are searching.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java">Geometry submesh = (Geometry) houseScene.getChild(<span class="string"><span class="delimiter">"</span><span class="content">door 12</span><span class="delimiter">"</span></span>);</code></pre>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="what-is-culling">What is Culling?</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>There are two types of culling: Face culling, and view frustrum culling.</p>
- </div>
- <div class="paragraph">
- <p><strong>Face culling</strong> means not drawing certain polygons of a mesh. Face culling behaviour is a property of the material.</p>
- </div>
- <div class="paragraph">
- <p>Usage: The “inside of a mesh (the so called backface) is typically never visible to the player, and as an optimization, the <code>Back</code> mode skips calculating all backfaces by default. Activating the <code>Off</code> or <code>Front</code> modes can be useful when you are debugging <a href="../../jme3/advanced/custom_meshes.html">custom meshes</a> and try to identify accidental inside-out faces.</p>
- </div>
- <div class="paragraph">
- <p>You can switch the com.jme3.material.RenderState.FaceCullMode to either:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p><code>FaceCullMode.Back</code> (default) – Only the frontsides of a mesh are drawn. Backface culling is the default behaviour.</p>
- </li>
- <li>
- <p><code>FaceCullMode.Front</code> – Only the backsides of a mesh are drawn. A mesh with frontface culling will most likely be invisible. Used for debugging “inside-out custom meshes.</p>
- </li>
- <li>
- <p><code>FaceCullMode.FrontAndBack</code> – Use this to make a mesh temporarily invisible.</p>
- </li>
- <li>
- <p><code>FaceCullMode.Off</code> – Every side of the mesh is drawn. Looks normal, but slows down large scenes.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>Example:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java">material.getAdditionalRenderState().setFaceCullMode(FaceCullMode.FrontAndBack);</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p><strong>View frustum culling</strong> refers to not drawing (and not even calculating) certain whole models in the scene. At any given moment, half of the scene is behind the player and out of sight anyway. View frustum culling is an optimization to not calculate scene elements that are not visible – elements that are “outside the view frustrum.</p>
- </div>
- <div class="paragraph">
- <p>The decision what is visible and what not, is done automatically by the engine (<code>CullHint.Dynamic</code>). Optionally, you can manually control whether the engine culls individual spatials (and children) from the scene graph:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p><code>CullHint.Dynamic</code> – Default, faster because it doesn’t waste time with objects that are out of view.</p>
- </li>
- <li>
- <p><code>CullHint.Never</code> – Calculate and draw everything always (even if it does not end up on the user’s screen because it’s out of sight). Slower, but can be used while debugging custom meshes.</p>
- </li>
- <li>
- <p><code>CullHint.Always</code> – The whole spatial is culled and is not visible. A fast way to hide a Spatial temporarily. Culling a Spatial is faster then detaching it, but it uses more memory.</p>
- </li>
- <li>
- <p><code>CullHint.Inherit</code> – Inherit culling behaviour from parent node.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>Example:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java">spatial.setCullHint(CullHint.Never); <span class="comment">// always drawn</span></code></pre>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="see-also">See also</h2>
- <div class="sectionbody">
- <div class="ulist">
- <ul>
- <li>
- <p><a href="../../jme3/intermediate/optimization.html">Optimization</a> – The GeometryBatchFactory class batches several Geometries into meshes with each their own texture.</p>
- </li>
- <li>
- <p><a href="../../jme3/advanced/traverse_scenegraph.html">Traverse SceneGraph</a> – Find any Node or Geometry in the scenegraph.</p>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div id="footer">
- <div id="footer-text">
- Version <br>
- Last updated 2016-06-05 15:58:32 UTC
- </div>
- </div>
- </body>
- </html>
|