1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252 |
- <!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">
- <title>jMonkeyEngine 3 Tutorial (13) - Hello Physics</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>jMonkeyEngine 3 Tutorial (13) - Hello Physics</h1>
- <div id="toc" class="toc2">
- <div id="toctitle">Table of Contents</div>
- <ul class="sectlevel1">
- <li><a href="#sample-code">Sample Code</a></li>
- <li><a href="#creating-bricks-and-cannon-balls">Creating Bricks and Cannon Balls</a>
- <ul class="sectlevel2">
- <li><a href="#geometries">Geometries</a></li>
- <li><a href="#rigidbodycontrol-cannonball">RigidBodyControl: Cannonball</a></li>
- </ul>
- </li>
- <li><a href="#creating-the-scene">Creating the Scene</a></li>
- <li><a href="#the-cannon-ball-shooting-action">The Cannon Ball Shooting Action</a></li>
- <li><a href="#moving-a-physical-spatial">Moving a Physical Spatial</a></li>
- <li><a href="#excercises">Excercises</a>
- <ul class="sectlevel2">
- <li><a href="#exercise-1-debug-shapes">Exercise 1: Debug Shapes</a></li>
- <li><a href="#exercise-2-no-mo-static">Exercise 2: No Mo' Static</a></li>
- <li><a href="#exercise-3-behind-the-curtain">Exercise 3: Behind the Curtain</a></li>
- </ul>
- </li>
- <li><a href="#conclusion">Conclusion</a></li>
- </ul>
- </div>
- </div>
- <div id="content">
- <div id="preamble">
- <div class="sectionbody">
- <div class="paragraph">
- <p>Previous: <a href="hello_effects.html">Hello Effects</a>,
- Next: <a href="jme3.html">JME 3 documentation</a></p>
- </div>
- <div class="paragraph">
- <p>Do you remember the <a href="hello_collision.html">Hello Collision</a> tutorial where you made the model of a town solid and walked through it in a first-person perspective? Then you may remember that, for the simulation of physical forces, jME3 integrates the <a href="http://jbullet.advel.cz/">jBullet</a> library.</p>
- </div>
- <div class="paragraph">
- <p>Apart from making models “solid, the most common use cases for physics in 3D games are:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>Driving vehicles with suspensions, tyre friction, ramp jumping, drifting – Example: car racers</p>
- </li>
- <li>
- <p>Rolling and bouncing balls – Example: pong, pool billiard, bowling</p>
- </li>
- <li>
- <p>Sliding and falling boxes – Example: Breakout, Arkanoid</p>
- </li>
- <li>
- <p>Exposing objects to forces and gravity – Example: spaceships or zero-g flight</p>
- </li>
- <li>
- <p>Animating ragdolls – Example: “realistic character simulations</p>
- </li>
- <li>
- <p>Swinging pendulums, rope bridges, flexible chains, and much more…</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>All these physical properties can be simulated in JME3. Let’s have a look at a simulation of physical forces in this example where you shoot cannon balls at a brick wall.</p>
- </div>
- <div class="imageblock" style="text-align: center">
- <div class="content">
- <img src="images/jme3/beginner/beginner-physics.png" alt="beginner-physics.png" height="291">
- </div>
- </div>
- <div class="paragraph">
- <p>““““</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="sample-code">Sample Code</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>Thanks to double1984 for contributing this fun sample!</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java">----<span class="keyword">package</span> <span class="namespace">jme3test.helloworld</span>;</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>import com.jme3.app.SimpleApplication;
- import com.jme3.asset.TextureKey;
- import com.jme3.bullet.BulletAppState;
- import com.jme3.bullet.control.RigidBodyControl;
- import com.jme3.font.BitmapText;
- import com.jme3.input.MouseInput;
- import com.jme3.input.controls.ActionListener;
- import com.jme3.input.controls.MouseButtonTrigger;
- import com.jme3.material.Material;
- import com.jme3.math.Vector2f;
- import com.jme3.math.Vector3f;
- import com.jme3.scene.Geometry;
- import com.jme3.scene.shape.Box;
- import com.jme3.scene.shape.Sphere;
- import com.jme3.scene.shape.Sphere.TextureMode;
- import com.jme3.texture.Texture;
- import com.jme3.texture.Texture.WrapMode;</p>
- </div>
- <div class="paragraph">
- <p>/**
- * Example 12 - how to give objects physical properties so they bounce and fall.
- * @author base code by double1984, updated by zathras
- */
- public class HelloPhysics extends SimpleApplication {</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>public static void main(String args[]) {
- HelloPhysics app = new HelloPhysics();
- app.start();
- }</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** Prepare the Physics Application State (jBullet) */
- private BulletAppState bulletAppState;</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** Prepare Materials */
- Material wall_mat;
- Material stone_mat;
- Material floor_mat;</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** Prepare geometries and physical nodes for bricks and cannon balls. */
- private RigidBodyControl brick_phy;
- private static final Box box;
- private RigidBodyControl ball_phy;
- private static final Sphere sphere;
- private RigidBodyControl floor_phy;
- private static final Box floor;</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** dimensions used for bricks and wall */
- private static final float brickLength = 0.48f;
- private static final float brickWidth = 0.24f;
- private static final float brickHeight = 0.12f;</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>static {
- /** Initialize the cannon ball geometry */
- sphere = new Sphere(32, 32, 0.4f, true, false);
- sphere.setTextureMode(TextureMode.Projected);
- /** Initialize the brick geometry */
- box = new Box(brickLength, brickHeight, brickWidth);
- box.scaleTextureCoordinates(new Vector2f(1f, .5f));
- /** Initialize the floor geometry */
- floor = new Box(10f, 0.1f, 5f);
- floor.scaleTextureCoordinates(new Vector2f(3, 6));
- }</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>@Override
- public void simpleInitApp() {
- /** Set up Physics Game */
- bulletAppState = new BulletAppState();
- stateManager.attach(bulletAppState);
- //bulletAppState.getPhysicsSpace().enableDebug(assetManager);</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre> /** Configure cam to look at scene */
- cam.setLocation(new Vector3f(0, 4f, 6f));
- cam.lookAt(new Vector3f(2, 2, 0), Vector3f.UNIT_Y);
- /** Add InputManager action: Left click triggers shooting. */
- inputManager.addMapping("shoot",
- new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
- inputManager.addListener(actionListener, "shoot");
- /** Initialize the scene, materials, and physics space */
- initMaterials();
- initWall();
- initFloor();
- initCrossHairs();
- }</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/**
- * Every time the shoot action is triggered, a new cannon ball is produced.
- * The ball is set up to fly from the camera position in the camera direction.
- */
- private ActionListener actionListener = new ActionListener() {
- public void onAction(String name, boolean keyPressed, float tpf) {
- if (name.equals("shoot") && !keyPressed) {
- makeCannonBall();
- }
- }
- };</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** Initialize the materials used in this scene. */
- public void initMaterials() {
- wall_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
- TextureKey key = new TextureKey("Textures/Terrain/BrickWall/BrickWall.jpg");
- key.setGenerateMips(true);
- Texture tex = assetManager.loadTexture(key);
- wall_mat.setTexture("ColorMap", tex);</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>stone_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
- TextureKey key2 = new TextureKey("Textures/Terrain/Rock/Rock.PNG");
- key2.setGenerateMips(true);
- Texture tex2 = assetManager.loadTexture(key2);
- stone_mat.setTexture("ColorMap", tex2);</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre> floor_mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
- TextureKey key3 = new TextureKey("Textures/Terrain/Pond/Pond.jpg");
- key3.setGenerateMips(true);
- Texture tex3 = assetManager.loadTexture(key3);
- tex3.setWrap(WrapMode.Repeat);
- floor_mat.setTexture("ColorMap", tex3);
- }</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** Make a solid floor and add it to the scene. */
- public void initFloor() {
- Geometry floor_geo = new Geometry("Floor", floor);
- floor_geo.setMaterial(floor_mat);
- floor_geo.setLocalTranslation(0, -0.1f, 0);
- this.rootNode.attachChild(floor_geo);
- /* Make the floor physical with mass 0.0f! */
- floor_phy = new RigidBodyControl(0.0f);
- floor_geo.addControl(floor_phy);
- bulletAppState.getPhysicsSpace().add(floor_phy);
- }</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** This loop builds a wall out of individual bricks. */
- public void initWall() {
- float startpt = brickLength / 4;
- float height = 0;
- for (int j = 0; j < 15; j++) {
- for (int i = 0; i < 6; i++) {
- Vector3f vt =
- new Vector3f(i * brickLength * 2 + startpt, brickHeight + height, 0);
- makeBrick(vt);
- }
- startpt = -startpt;
- height += 2 * brickHeight;
- }
- }</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** This method creates one individual physical brick. */
- public void makeBrick(Vector3f loc) {
- /** Create a brick geometry and attach to scene graph. */
- Geometry brick_geo = new Geometry("brick", box);
- brick_geo.setMaterial(wall_mat);
- rootNode.attachChild(brick_geo);
- /** Position the brick geometry */
- brick_geo.setLocalTranslation(loc);
- /** Make brick physical with a mass > 0.0f. */
- brick_phy = new RigidBodyControl(2f);
- /** Add physical brick to physics space. */
- brick_geo.addControl(brick_phy);
- bulletAppState.getPhysicsSpace().add(brick_phy);
- }</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>/** This method creates one individual physical cannon ball.
- * By defaul, the ball is accelerated and flies
- * from the camera position in the camera direction.*/
- public void makeCannonBall() {
- /** Create a cannon ball geometry and attach to scene graph. */
- Geometry ball_geo = new Geometry("cannon ball", sphere);
- ball_geo.setMaterial(stone_mat);
- rootNode.attachChild(ball_geo);
- /** Position the cannon ball */
- ball_geo.setLocalTranslation(cam.getLocation());
- /** Make the ball physcial with a mass > 0.0f */
- ball_phy = new RigidBodyControl(1f);
- /** Add physical ball to physics space. */
- ball_geo.addControl(ball_phy);
- bulletAppState.getPhysicsSpace().add(ball_phy);
- /** Accelerate the physcial ball to shoot it. */
- ball_phy.setLinearVelocity(cam.getDirection().mult(25));
- }</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre> /** A plus sign used as crosshairs to help the player with aiming.*/
- protected void initCrossHairs() {
- guiNode.detachAllChildren();
- guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
- BitmapText ch = new BitmapText(guiFont, false);
- ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
- ch.setText("+"); // fake crosshairs :)
- ch.setLocalTranslation( // center
- settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
- settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
- guiNode.attachChild(ch);
- }
- }</pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre>You should see a brick wall. Click to shoot cannon balls. Watch the bricks fall and bounce off one another!
- == A Basic Physics Application
- In the previous tutorials, you used static Geometries (boxes, spheres, and models) that you placed in the scene. Depending on their translation, Geometries can “float in mid-air and even overlap – they are not affected by “gravity and have no physical mass. This tutorial shows how to add physical properties to Geometries.
- As always, start with a standard com.jme3.app.SimpleApplication. To activate physics, create a com.jme3.bullet.BulletAppState, and and attach it to the SimpleApplication's AppState manager.
- [source,java]</pre>
- </div>
- </div>
- <div class="paragraph">
- <p>public class HelloPhysics extends SimpleApplication {
- private BulletAppState bulletAppState;</p>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre> public void simpleInitApp() {
- bulletAppState = new BulletAppState();
- stateManager.attach(bulletAppState);
- ...
- }
- ...
- }----
- The BulletAppState gives the game access to a PhysicsSpace. The PhysicsSpace lets you use com.jme3.bullet.control.PhysicsControls that add physical properties to Nodes.</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="creating-bricks-and-cannon-balls">Creating Bricks and Cannon Balls</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="geometries">Geometries</h3>
- <div class="paragraph">
- <p>In this “shoot at the wall example, you use Geometries such as cannon balls and bricks. Geometries contain meshes, such as Shapes. Let’s create and initialize some Shapes: Boxes and Spheres.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"> <span class="comment">/** Prepare geometries and physical nodes for bricks and cannon balls. */</span>
- <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="predefined-type">Box</span> box;
- <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> Sphere sphere;
- <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="predefined-type">Box</span> floor;
- <span class="comment">/** dimensions used for bricks and wall */</span>
- <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">float</span> brickLength = <span class="float">0.48f</span>;
- <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">float</span> brickWidth = <span class="float">0.24f</span>;
- <span class="directive">private</span> <span class="directive">static</span> <span class="directive">final</span> <span class="type">float</span> brickHeight = <span class="float">0.12f</span>;
- <span class="directive">static</span> {
- <span class="comment">/** Initialize the cannon ball geometry */</span>
- sphere = <span class="keyword">new</span> Sphere(<span class="integer">32</span>, <span class="integer">32</span>, <span class="float">0.4f</span>, <span class="predefined-constant">true</span>, <span class="predefined-constant">false</span>);
- sphere.setTextureMode(TextureMode.Projected);
- <span class="comment">/** Initialize the brick geometry */</span>
- box = <span class="keyword">new</span> <span class="predefined-type">Box</span>(brickLength, brickHeight, brickWidth);
- box.scaleTextureCoordinates(<span class="keyword">new</span> Vector2f(<span class="float">1f</span>, <span class="float">.5f</span>));
- <span class="comment">/** Initialize the floor geometry */</span>
- floor = <span class="keyword">new</span> <span class="predefined-type">Box</span>(<span class="float">10f</span>, <span class="float">0.1f</span>, <span class="float">5f</span>);
- floor.scaleTextureCoordinates(<span class="keyword">new</span> Vector2f(<span class="integer">3</span>, <span class="integer">6</span>));
- }----
- === RigidBodyControl: Brick
- We want to create brick Geometries from those boxes. For each Geometry with physical properties, you create a RigidBodyControl.
- [source,java]</code></pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre>private RigidBodyControl brick_phy;</pre>
- </div>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre>The custom `makeBrick(loc)` methods creates individual bricks at the location `loc`. A brick has the following properties:
- * It has a visible Geometry `brick_geo` (Box Shape Geometry).
- * It has physical properties `brick_phy` (RigidBodyControl)
- [source,java]</pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre> public void makeBrick(Vector3f loc) {
- /** Create a brick geometry and attach to scene graph. */
- Geometry brick_geo = new Geometry("brick", box);
- brick_geo.setMaterial(wall_mat);
- rootNode.attachChild(brick_geo);
- /** Position the brick geometry */
- brick_geo.setLocalTranslation(loc);
- /** Make brick physical with a mass > 0.0f. */
- brick_phy = new RigidBodyControl(2f);
- /** Add physical brick to physics space. */
- brick_geo.addControl(brick_phy);
- bulletAppState.getPhysicsSpace().add(brick_phy);
- }----
- This code sample does the following:</pre>
- </div>
- </div>
- <div class="olist arabic">
- <ol class="arabic">
- <li>
- <p>You create a brick Geometry brick_geo. A Geometry describes the shape and look of an object.</p>
- <div class="ulist">
- <ul>
- <li>
- <p>brick_geo has a box shape</p>
- </li>
- <li>
- <p>brick_geo has a brick-colored material.</p>
- </li>
- </ul>
- </div>
- </li>
- <li>
- <p>You attach brick_geo to the rootNode</p>
- </li>
- <li>
- <p>You position brick_geo at <code>loc</code>.</p>
- </li>
- <li>
- <p>You create a RigidBodyControl brick_phy for brick_geo.</p>
- <div class="ulist">
- <ul>
- <li>
- <p>brick_phy has a mass of 2f.</p>
- </li>
- <li>
- <p>You add brick_phy to brick_geo.</p>
- </li>
- <li>
- <p>You register brick_phy to the PhysicsSpace.</p>
- </li>
- </ul>
- </div>
- </li>
- </ol>
- </div>
- </div>
- <div class="sect2">
- <h3 id="rigidbodycontrol-cannonball">RigidBodyControl: Cannonball</h3>
- <div class="paragraph">
- <p>You notice that the cannon ball is created in the same way, using the custom <code>makeCannonBall()</code> method. The cannon ball has the following properties:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>It has a visible Geometry <code>ball_geo</code> (Sphere Shape Geometry)</p>
- </li>
- <li>
- <p>It has physical properties <code>ball_phy</code> (RigidBodyControl)</p>
- </li>
- </ul>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"> <span class="comment">/** Create a cannon ball geometry and attach to scene graph. */</span>
- Geometry ball_geo = <span class="keyword">new</span> Geometry(<span class="string"><span class="delimiter">"</span><span class="content">cannon ball</span><span class="delimiter">"</span></span>, sphere);
- ball_geo.setMaterial(stone_mat);
- rootNode.attachChild(ball_geo);
- <span class="comment">/** Position the cannon ball */</span>
- ball_geo.setLocalTranslation(cam.getLocation());
- <span class="comment">/** Make the ball physcial with a mass > 0.0f */</span>
- ball_phy = <span class="keyword">new</span> RigidBodyControl(<span class="float">1f</span>);
- <span class="comment">/** Add physical ball to physics space. */</span>
- ball_geo.addControl(ball_phy);
- bulletAppState.getPhysicsSpace().add(ball_phy);
- <span class="comment">/** Accelerate the physcial ball to shoot it. */</span>
- ball_phy.setLinearVelocity(cam.getDirection().mult(<span class="integer">25</span>));
- ----
- This code sample does the following:
- . You create a ball Geometry ball_geo. A Geometry describes the shape and look of an object.
- ** ball_geo has a sphere shape
- ** ball_geo has a stone-colored material.
- . You attach ball_geo to the rootNode
- . You position ball_geo at the camera location.
- . You create a RigidBodyControl ball_phy <span class="keyword">for</span> ball_geo.
- ** ball_phy has a mass of <span class="float">1f</span>.
- ** You add ball_phy to ball_geo.
- ** You register ball_phy to the PhysicsSpace.
- Since you are shooting cannon balls, the last line accelerates the ball in the direction the camera is looking, with a speed of <span class="float">25f</span>.
- === RigidBodyControl: Floor
- The (<span class="directive">static</span>) floor has one important difference compared to the (dynamic) bricks and cannonballs: *Static objects have a mass of zero.*
- As before, you write a custom <span class="error">`</span>initFloor()<span class="error">`</span> method that creates a flat box with a rock texture that you use as floor. The floor has the following properties:
- * It has a visible Geometry <span class="error">`</span>floor_geo<span class="error">`</span> (<span class="predefined-type">Box</span> <span class="predefined-type">Shape</span> Geometry)
- * It has physical properties <span class="error">`</span>floor_phy<span class="error">`</span> (RigidBodyControl)
- [source,java]</code></pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre> public void initFloor() {
- Geometry floor_geo = new Geometry("Floor", floor);
- floor_geo.setMaterial(floor_mat);
- floor_geo.setLocalTranslation(0, -0.1f, 0);
- this.rootNode.attachChild(floor_geo);
- /* Make the floor physical with mass 0.0f! */
- floor_phy = new RigidBodyControl(0.0f);
- floor_geo.addControl(floor_phy);
- bulletAppState.getPhysicsSpace().add(floor_phy);
- }----
- This code sample does the following:</pre>
- </div>
- </div>
- <div class="olist arabic">
- <ol class="arabic">
- <li>
- <p>You create a floor Geometry floor_geo. A Geometry describes the shape and look of an object.</p>
- <div class="ulist">
- <ul>
- <li>
- <p>floor_geo has a box shape</p>
- </li>
- <li>
- <p>floor_geo has a pebble-colored material.</p>
- </li>
- </ul>
- </div>
- </li>
- <li>
- <p>You attach floor_geo to the rootNode</p>
- </li>
- <li>
- <p>You position floor_geo a bit below y=0 (to prevent overlap with other PhysicControl’ed Spatials).</p>
- </li>
- <li>
- <p>You create a RigidBodyControl floor_phy for floor_geo.</p>
- <div class="ulist">
- <ul>
- <li>
- <p>floor_phy has a mass of 0f emoji:</p>
- </li>
- <li>
- <p>You add floor_phy to floor_geo.</p>
- </li>
- <li>
- <p>You register floor_phy to the PhysicsSpace.</p>
- </li>
- </ul>
- </div>
- </li>
- </ol>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="creating-the-scene">Creating the Scene</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>Let’s have a quick look at the custom helper methods:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p><code>initMaterial()</code> – This method initializes all the materials we use in this demo.</p>
- </li>
- <li>
- <p><code>initWall()</code> – A double loop that generates a wall by positioning brick objects: 15 rows high with 6 bricks per row. It’s important to space the physical bricks so they do not overlap.</p>
- </li>
- <li>
- <p><code>initCrossHairs()</code> – This method simply displays a plus sign that you use as crosshairs for aiming. Note that screen elements such as crosshairs are attached to the <code>guiNode</code>, not the <code>rootNode</code>!</p>
- </li>
- <li>
- <p><code>initInputs()</code> – This method sets up the click-to-shoot action.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>These methods are each called once from the <code>simpleInitApp()</code> method at the start of the game. As you see, you can write any number of custom methods to set up your game’s scene.</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="the-cannon-ball-shooting-action">The Cannon Ball Shooting Action</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>In the <code>initInputs()</code> method, you add an input mapping that triggers a shoot action when the left mouse button is pressed.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java"> <span class="directive">private</span> <span class="type">void</span> initInputs() {
- inputManager.addMapping(<span class="string"><span class="delimiter">"</span><span class="content">shoot</span><span class="delimiter">"</span></span>,
- <span class="keyword">new</span> MouseButtonTrigger(MouseInput.BUTTON_LEFT));
- inputManager.addListener(actionListener, <span class="string"><span class="delimiter">"</span><span class="content">shoot</span><span class="delimiter">"</span></span>);
- }----
- You define the actual action of shooting a <span class="keyword">new</span> cannon ball as follows:
- [source,java]</code></pre>
- </div>
- </div>
- <div class="literalblock">
- <div class="content">
- <pre> private ActionListener actionListener = new ActionListener() {
- public void onAction(String name, boolean keyPressed, float tpf) {
- if (name.equals("shoot") && !keyPressed) {
- makeCannonBall();
- }
- }
- };----
- In the moment the cannonball appears in the scene, it flies off with the velocity (and in the direction) that you specified using `setLinearVelocity()` inside `makeCannonBall()`. The newly created cannon ball flies off, hits the wall, and exerts a _physical force_ that impacts individual bricks.</pre>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="moving-a-physical-spatial">Moving a Physical Spatial</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>The location of the dynamic Spatial is controlled by its RigidBodyControl. Move the RigidBodyControl to move the Spatial. If it’s a dynamic PhysicsControl, you can use setLinearVelocity() and apply forces and torques to it. Other RigidBodyControl’led objects can push the dynamic Spatial around (like pool/billiard balls).</p>
- </div>
- <div class="paragraph">
- <p>You can make Spatials that are not dynamic: Switch the RigidBodyControl to setKinematic(true) to have it move along with its Spatial.</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>A kinematic is unaffected by forces or gravity, which means it can float in mid-air and cannot be pushed away by dynamic “cannon balls etc.</p>
- </li>
- <li>
- <p>A kinematic RigidBody has a mass.</p>
- </li>
- <li>
- <p>A kinematic can be moved and can exert forces on dynamic RigidBodys. This means you can use a kinematic node as a billiard cue or a remote-controlled battering ram.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>Learn more about static versus kinematic versus dynamic in the <a href="jme3/advanced/physics.html">advanced physics doc</a>.</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="excercises">Excercises</h2>
- <div class="sectionbody">
- <div class="sect2">
- <h3 id="exercise-1-debug-shapes">Exercise 1: Debug Shapes</h3>
- <div class="paragraph">
- <p>Add the following line after the bulletAppState initialization.</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="CodeRay highlight"><code data-lang="java">----bulletAppState.getPhysicsSpace().enableDebug(assetManager);----
- Now you see the collisionShapes of the bricks and spheres, and the floor highlighted.</code></pre>
- </div>
- </div>
- </div>
- <div class="sect2">
- <h3 id="exercise-2-no-mo-static">Exercise 2: No Mo' Static</h3>
- <div class="paragraph">
- <p>What happens if you give a static node, such as the floor, a mass of more than 0.0f?</p>
- </div>
- </div>
- <div class="sect2">
- <h3 id="exercise-3-behind-the-curtain">Exercise 3: Behind the Curtain</h3>
- <div class="paragraph">
- <p>Fill your scene with walls, bricks, and cannon balls. When do you begin to see a performance impact?</p>
- </div>
- <div class="paragraph">
- <p>Popular AAA games use a clever mix of physics, animation and prerendered graphics to give you the illusion of a real, “physical world. Think of your favorite video games and try to spot where and how the game designers trick you into believing that the whole scene is physical. For example, think of a building “breaking into 4-8 parts after an explosion. The pieces most likely fly on predefined (so called kinematic) paths and are only replaced by dynamic Spatials after they touch the ground… Now that you start to implement game physics yourself, look behind the curtain!</p>
- </div>
- <div class="paragraph">
- <p>Using physics everywhere in a game sounds like a cool idea, but it is easily overused. Although the physics nodes are put to “sleep when they are not moving, creating a world solely out of dynamic physics nodes will quickly bring you to the limits of your computer’s capabilities.</p>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="conclusion">Conclusion</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>You have learned how to activate the jBullet PhysicsSpace in an application by adding a <code>BulletAppState</code>. You have created PhysicsControls for simple Shape-based Geometries (for more complex shapes, read up on <a href="jme3/advanced/physics.html">CollisionShapes</a>). You have learned that physical objects are not only attached to the rootNode, but also registered to the PhysicsSpace. You know that it makes a difference whether a physical object has a mass (dynamic) or not (static). You are aware that overusing physics has a huge performance impact.</p>
- </div>
- <div class="paragraph">
- <p>–<a href="jme3.html">combining what you have learned</a><a href="http://jmonkeyengine.org/groups/free-announcements/forum/">Free Announcements Forum</a></p>
- </div>
- <div class="paragraph">
- <p><tags><tag target="beginner" /><tag target="intro" /><tag target="physics" /><tag target="documentation" /><tag target="input" /><tag target="model" /><tag target="control" /></tags></p>
- </div>
- </div>
- </div>
- </div>
- <div id="footer">
- <div id="footer-text">
- Last updated 2016-05-21 23:44:18 UTC
- </div>
- </div>
- </body>
- </html>
|