| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831 |
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width,initial-scale=1">
- <title>3-D Rotation :: jMonkeyEngine Docs</title>
- <link rel="canonical" href="https://wiki.jmonkeyengine.org/docs/tutorials/intermediate/rotate.html">
- <link rel="prev" href="math_cheet_sheet.html">
- <link rel="next" href="math_video_tutorials.html">
- <meta name="generator" content="Antora 2.3.3">
- <link rel="stylesheet" href="../../../_/css/site.css">
- <meta property="og:image" content="https://wiki.jmonkeyengine.org/_/img/iconx128.png">
- <meta property="og:description" content="3-D Rotation">
- <meta property="og:title" content="jMonkeyEngine Docs">
- <link rel="stylesheet" href="../../../_/css/site-extra.css">
- <link rel="stylesheet" href="../../../_/css/vendor/docsearch.min.css">
- <!-- fetched from https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css -->
- <link rel="icon" href="../../../_/img/favicon.ico" type="image/x-icon">
- </head>
- <body class="article">
- <header class="header">
- <nav class="navbar">
- <div class="navbar-brand">
- <a class="navbar-item" href="https://wiki.jmonkeyengine.org">
- <img alt="" src="../../../_/img/jme-logo.png" height="32" type="image/x-icon">
- </a>
- <div class="navbar-item hide-for-print">
- <input id="search-input" type="text" placeholder="Search docs">
- </div>
- <button class="navbar-burger" data-target="topbar-nav">
- <span></span>
- <span></span>
- <span></span>
- </button>
- </div>
- <div id="topbar-nav" class="navbar-menu">
- <div class="navbar-end">
- <div class="navbar-item theme-switch-wrapper">
- <label class="theme-switch" for="checkbox">
- <input type="checkbox" id="checkbox" />
- <div class="slider round"></div>
- </label>
- </div>
- <a class="navbar-item" href="https://github.com/jmonkeyengine/wiki">Github</a>
- </div>
- </div>
- </nav>
- </header>
- <div class="body">
- <div class="nav-container" data-component="docs" data-version="master">
- <aside class="nav">
- <div class="panels">
- <div class="nav-panel-menu is-active" data-panel="menu">
- <nav class="nav-menu">
- <h3 class="title"><a href="../../documentation.html">Docs</a></h3>
- <ul class="nav-list">
- <li class="nav-item" data-depth="0">
- <ul class="nav-list">
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="../../documentation.html">Getting Started</a>
- </li>
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="https://javadoc.jmonkeyengine.org/v3.3.2-stable">JavaDoc</a>
- </li>
- <li class="nav-item" data-depth="1">
- <a class="nav-link" href="../../jme3.html">jMonkeyEngine 3</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="0">
- <ul class="nav-list">
- <li class="nav-item" data-depth="1">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Tutorials</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <a class="nav-link" href="../beginner/beginner.html">Beginner</a>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_simpleapplication.html">Hello SimpleApplication</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_node.html">Hello Node</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_asset.html">Hello Asset</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_main_event_loop.html">Hello Update Loop</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_input_system.html">Hello Input System</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_material.html">Hello Material</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_animation.html">Hello Animation</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_picking.html">Hello Picking</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_collision.html">Hello Collision</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_terrain.html">Hello Terrain</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_audio.html">Hello Audio</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_effects.html">Hello Effects</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../beginner/hello_physics.html">Hello Physics</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Intermediate</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="best_practices.html">Best Practices</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="optimization.html">Optimization</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="faq.html">Frequently Asked Questions</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="math_for_dummies.html">Math for Dummies</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="math.html">Math overview</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="math_cheet_sheet.html">3D math "cheat sheet"</a>
- </li>
- <li class="nav-item is-current-page" data-depth="3">
- <a class="nav-link" href="rotate.html">3-D Rotation</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="math_video_tutorials.html">Math video tutorial series</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="multi-media_asset_pipeline.html">Multi-Media Asset Pipeline</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="scenegraph_for_dummies.html">Scene Graph for Dummies</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="terminology.html">3D Graphics Terminology</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="how_to_use_materials.html">How to Use Materials</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="transparency_sorting.html">Transparency Sorting</a>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="0">
- <ul class="nav-list">
- <li class="nav-item" data-depth="1">
- <button class="nav-item-toggle"></button>
- <a class="nav-link" href="../../sdk/sdk.html">SDK</a>
- <ul class="nav-list">
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Video Tutorials</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">SDK Use Case Tutorials</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=-OzRZscLlHY">Demo 1 (Quixote demo)</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=6-YWxD3JByE">Demo 2 (Models and Materials)</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="3">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">SDK Tutorials</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=M1_0pbeyJzI">Basics</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=nL7woH40i5c">Importing Models</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=DUmgAjiNzhY">Dragging&Dropping Nodes</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=ntPAmtsQ6eM">Scene Composing</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=zgPV3W6dD4s">Terrain with Collision Shape</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=Feu3-mrpolc">Working with Materials</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=MNDiZ9YHIpM">Custom Controls</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=oZnssg8TBWQ">WebStart Deployment</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="http://www.youtube.com/watch?v=D7JM4VMKqPc">Animation and Effect TrackEditing</a>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Getting Started</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/update_center.html">Updating jMonkeyEngine SDK</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/troubleshooting.html">Troubleshooting</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Java Development Features</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/project_creation.html">Project Creation</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/code_editor.html">Code Editor and Palette</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/version_control.html">File Version Control</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/debugging_profiling_testing.html">Debug, Profile, Test</a>
- </li>
- <li class="nav-item" data-depth="3">
- <button class="nav-item-toggle"></button>
- <a class="nav-link" href="../../sdk/application_deployment.html">Application Deployment</a>
- <ul class="nav-list">
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../../sdk/default_build_script.html">Default Build Script</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../../sdk/android.html">Android</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../../sdk/android_cheat_sheet.html">Android Cheat Sheet</a>
- </li>
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../../sdk/ios.html">iOS</a>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Unique Features</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <button class="nav-item-toggle"></button>
- <a class="nav-link" href="../../sdk/model_loader_and_viewer.html">Import, View, Convert Models</a>
- <ul class="nav-list">
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="../../sdk/asset_packs.html">Asset Packs</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/scene_explorer.html">The SceneExplorer</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/scene_composer.html">Composing a Scene</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/terrain_editor.html">Terrain Editor</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/sample_code.html">Sample Code</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/material_editing.html">Material Editing</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/font_creation.html">Creating Bitmap Fonts</a>
- </li>
- <li class="nav-item" data-depth="3">
- <button class="nav-item-toggle"></button>
- <a class="nav-link" href="https://hub.jmonkeyengine.org/t/effecttrack-and-audiotrack-editing-in-the-sdk/23378">Audio and Effect Track Editing</a>
- <ul class="nav-list">
- <li class="nav-item" data-depth="4">
- <a class="nav-link" href="https://www.youtube.com/watch?v=D7JM4VMKqPc">Video: Effect and AudioTrack editing in jMonkeyEngine 3 sdk</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/filters.html">Post-Processor Filter Editor and Viewer</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../jme3/advanced/application_states.html">Application States</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../jme3/advanced/custom_controls.html">Custom Controls</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/vehicle_creator.html">Vehicle Creator</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Advanced Usage</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/build_platform.html">Building jMonkeyEngine SDK</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/use_own_jme.html#.adoc">Using your own (modified) version of jME3 in jMonkeyEngine SDK</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/increasing_heap_memory.html">Increasing Heap Memory</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/log_files.html">Log Files</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <span class="nav-text">Available external plugins</span>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../jme3/contributions.html">Contributions</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/neotexture.html">Neo Texture Editor for procedural textures</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="http://www.youtube.com/watch?v=yS9a9o4WzL8">Video: Mesh Tool & Physics Editor</a>
- </li>
- </ul>
- </li>
- <li class="nav-item" data-depth="2">
- <button class="nav-item-toggle"></button>
- <a class="nav-link" href="../../sdk/development.html">Developing plugins for jMonkeyEngine SDK</a>
- <ul class="nav-list">
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/development/setup.html">Creating a plugin</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/development/general.html">Creating components</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/development/scene.html">The Main Scene</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/development/sceneexplorer.html">The Scene Explorer</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/development/projects_assets.html">Projects and Assets</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/development/extension_library.html">Create a library plugin from a jar file</a>
- </li>
- <li class="nav-item" data-depth="3">
- <a class="nav-link" href="../../sdk/development/model_loader.html">Create a new or custom model filetype and loader</a>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
- </nav>
- </div>
- <div class="nav-panel-explore" data-panel="explore">
- <div class="context">
- <span class="title">Docs</span>
- <span class="version">master</span>
- </div>
- <ul class="components">
- <li class="component is-current">
- <span class="title">Docs</span>
- <ul class="versions">
- <li class="version is-current is-latest">
- <a href="../../documentation.html">master</a>
- </li>
- </ul>
- </li>
- <li class="component">
- <span class="title">Wiki UI</span>
- <ul class="versions">
- <li class="version is-latest">
- <a href="../../../wiki-ui/index.html">master</a>
- </li>
- </ul>
- </li>
- </ul>
- </div>
- </div>
- </aside>
- </div>
- <main class="article">
- <div class="toolbar" role="navigation">
- <button class="nav-toggle"></button>
- <nav class="breadcrumbs" aria-label="breadcrumbs">
- <ul>
- <li><a href="../../documentation.html">Docs</a></li>
- <li>Tutorials</li>
- <li>Intermediate</li>
- <li><a href="rotate.html">3-D Rotation</a></li>
- </ul>
- </nav>
- <div class="edit-this-page"><a href="https://github.com/jMonkeyEngine/wiki/edit/master/docs/modules/tutorials/pages/intermediate/rotate.adoc">Edit this Page</a></div>
- </div>
- <div class="content">
- <article class="doc">
- <h1 class="page">3-D Rotation</h1>
- <div id="preamble">
- <div class="sectionbody">
- <div class="paragraph">
- <p><em>Bad news: 3D rotation is done using matrix calculus.<br>
- Good news: If you do not understand calculus, there are two simple rules how you get it right.</em></p>
- </div>
- <div class="paragraph">
- <p><strong>3D rotation</strong> is a crazy mathematical operation where you need to multiply all vertices in your object by four floating point numbers; the multiplication is referred to as concatenation, the array of four numbers {x,y,z,w} is referred to as <a href="../../jme3/quaternion.html" class="page">quaternion</a>. Don’t worry, the 3D engine does the tough work for you. All you need to know is:</p>
- </div>
- <div class="paragraph">
- <p><strong>The Quaternion</strong> is an object capable of deep-freezing and storing a rotation that you can apply to a 3D object.</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="using-quaternions-for-rotation"><a class="anchor" href="#using-quaternions-for-rotation"></a>Using Quaternions for Rotation</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>To store a rotation in a Quaternion, you must specify two things: The angle and the axis of the rotation.</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>The rotation angle is defined as a multiple of the number PI.</p>
- </li>
- <li>
- <p>The rotation axis is defined by a vector: Think of them in terms of “pitch”, “yaw”, and “roll”.</p>
- </li>
- </ul>
- </div>
- <div class="paragraph">
- <p>Example:</p>
- </div>
- <div class="listingblock">
- <div class="content">
- <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">/* This quaternion stores a 180 degree rolling rotation */
- Quaternion roll180 = new Quaternion();
- roll180.fromAngleAxis( FastMath.PI , new Vector3f(0,0,1) );
- /* The rotation is applied: The object rolls by 180 degrees. */
- thingamajig.setLocalRotation( roll180 );</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>So how to choose the right numbers for the Quaternion parameters? I’ll give you my cheat-sheet:</p>
- </div>
- <table class="tableblock frame-all grid-all stretch">
- <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"><strong>Rotation around Axis?</strong></th>
- <th class="tableblock halign-left valign-top"><strong>Use this Axis Vector!</strong></th>
- <th class="tableblock halign-left valign-top"><strong>Examples for this kind of rotation</strong></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>X axis</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>(1,0,0)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>A plane pitches. Nodding your head.</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>Y axis</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>(0,1,0)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>A plane yaws. A vehicle turns. Shaking your head.</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>Z axis</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>(0,0,1)</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>A plane rolls or banks. Cocking your head.</p>
- </div></div></td>
- </tr>
- </tbody>
- </table>
- <div class="admonitionblock note">
- <table>
- <tr>
- <td class="icon">
- <i class="fa icon-note" title="Note"></i>
- </td>
- <td class="content">
- <div class="paragraph">
- <p>These are the three most common examples – technically you can rotate around any axis expressed by a vector.</p>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <table class="tableblock frame-all grid-all stretch">
- <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"><strong>Angle?</strong></th>
- <th class="tableblock halign-left valign-top"><strong>Use Radians!</strong></th>
- <th class="tableblock halign-left valign-top"><strong>Examples</strong></th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>45 degrees</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>FastMath.PI / 4</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>eighth of a circle</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>90 degrees</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>FastMath.PI / 2</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>quarter circle, 3 o’clock</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>180 degrees</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>FastMath.PI</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>half circle, 6 o’clock</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>270 degrees</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>FastMath.PI * 3 / 2</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>three quarter circle, 9 o’clock</p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>360 degrees</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>FastMath.PI * 2</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>full circle, 12 o’clock <img class="emoji" draggable="false" height="24px" width="24px" src="https://twemoji.maxcdn.com/2/svg/1f609.svg" /></p>
- </div></div></td>
- </tr>
- <tr>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p><code>g</code> degrees</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>FastMath.PI * g / 180</p>
- </div></div></td>
- <td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
- <p>any angle <code>g</code></p>
- </div></div></td>
- </tr>
- </tbody>
- </table>
- <div class="admonitionblock important">
- <table>
- <tr>
- <td class="icon">
- <i class="fa icon-important" title="Important"></i>
- </td>
- <td class="content">
- <div class="paragraph">
- <p>You must specify angles in <a href="http://en.wikipedia.org/wiki/Radian">Radian</a>s (multiples or fractions of PI). If you use degrees, you will just get useless results.</p>
- </div>
- </td>
- </tr>
- </table>
- </div>
- <div class="paragraph">
- <p>How to use these tables to speficy a certain rotation:</p>
- </div>
- <div class="olist arabic">
- <ol class="arabic">
- <li>
- <p>Pick the appropriate vector from the axis table.</p>
- </li>
- <li>
- <p>Pick the appropriate radians value from the angle table.</p>
- </li>
- <li>
- <p>Create a Quaternion to store this rotation. <code>… fromAngleAxis( radians , vector )</code></p>
- </li>
- <li>
- <p>Apply the Quaternion to a node to rotate it. <code>… setLocalRotation(…)</code></p>
- </li>
- </ol>
- </div>
- <div class="paragraph">
- <p>Quaternion objects can be used as often as you want, so give them meaningfull names, like <code>roll90, pitch45, yaw180</code>.</p>
- </div>
- <div class="paragraph">
- <p><a href="http://moddb.wikia.com/wiki/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation">More about Quaternions</a>…</p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="code-sample"><a class="anchor" href="#code-sample"></a>Code Sample</h2>
- <div class="sectionbody">
- <div class="listingblock">
- <div class="content">
- <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">/* We start out with a horizontal object */
- Cylinder cylinder = new Cylinder("post", 10, 10, 1, 10);
- cylinder.setModelBound(new BoundingBox());
- /* Create a 90-degree-pitch Quaternion. */
- Quaternion pitch90 = new Quaternion();
- pitch90.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
- /* Apply the rotation to the object */
- cylinder.setLocalRotation(pitch90);
- /* Update the model. Now it's vertical. */
- cylinder.updateModelBound();
- cylinder.updateGeometry();</code></pre>
- </div>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="interpolating-rotations"><a class="anchor" href="#interpolating-rotations"></a>Interpolating Rotations</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>You can specify two rotations, and then have jme calculate (interpolate) the steps between two rotations:</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>com.jme3.math.Quaternion, slerp() – store an interpolated step between two rotations</p>
- <div class="ulist">
- <ul>
- <li>
- <p><a href="https://javadoc.jmonkeyengine.org/v3.3.2-stable/com/jme3/math/Quaternion.html">com.jme3.math.Quaternion</a></p>
- </li>
- </ul>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="adding-rotations"><a class="anchor" href="#adding-rotations"></a>Adding Rotations</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>You can concatenate (add) rotations: This means you turn the object first around one axis, then around the other, in one step.<br>
- <code>Quaternion myRotation = pitch90.mult(roll45); /* pitch and roll */</code></p>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="troubleshooting-rotations"><a class="anchor" href="#troubleshooting-rotations"></a>Troubleshooting Rotations</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>Does the object end up in an unexpected location, or at an unexpected angle? If you are getting weird results, check the following:</p>
- </div>
- <div class="olist arabic">
- <ol class="arabic">
- <li>
- <p>3-D transformations are non-commutative! This means it often makes a huge difference whether you first move a node and then rotate it around an axis, or first rotate the node around an axis and then move it. Make sure you code does what you mean to do.</p>
- </li>
- <li>
- <p>Are you intending to rotate around the object’s origin along an axis, or around another pivot point outside the object? If you are trying to <em>rotate an object around a pivot point</em>, you have to create an (invisible) pivot node first, and attach the object to it. Then apply the rotation to the <em>parental pivot node</em>, not to the child object itself!</p>
- </li>
- <li>
- <p>Did you enter the angle in degrees (0 - 360°) or radians (0 - 2*PI)? A 3D engine expects radians, so make sure to convert your values! Formula: <code>g° = FastMath.PI * g / 180</code></p>
- </li>
- <li>
- <p>Did you modify one of the pre-made constants like this?</p>
- <div class="openblock">
- <div class="content">
- <div class="listingblock">
- <div class="content">
- <pre class="highlightjs highlight"><code class="language-java hljs" data-lang="java">//Never do things like this!!!
- Quaternion.IDENTITY.fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_X);</code></pre>
- </div>
- </div>
- <div class="paragraph">
- <p>This looks normal enough, after-all, this is a constant right? Sorta, what you are really doing is setting a value to the static final constant <code>Quaternion.IDENTITY</code>.</p>
- </div>
- <div class="paragraph">
- <p>To quote one of the core team members.</p>
- </div>
- <div class="quoteblock">
- <div class="title">Do not modify the “constants”. You will have a shit-ton of really messed up errors.</div>
- <blockquote>
- You gain NOTHING by doing this, either. Just use new Quaternion().fromAngles() like a sane person.
- For a deeper explaination, see this forum thread: <a href="https://hub.jmonkeyengine.org/t/quaternion-bug/39060">Quaternion bug?</a>
- </blockquote>
- <div class="attribution">
- — pspeed<br>
- <cite>Core Team Member</cite>
- </div>
- </div>
- </div>
- </div>
- </li>
- </ol>
- </div>
- </div>
- </div>
- <div class="sect1">
- <h2 id="tip-matrix"><a class="anchor" href="#tip-matrix"></a>Tip: Matrix</h2>
- <div class="sectionbody">
- <div class="paragraph">
- <p>This here is just about rotation, but there are three types of 3-D transformation: rotate, scale, and translate.</p>
- </div>
- <div class="paragraph">
- <p>You can do all transformations in individual steps (and then update the objects geometry and bounds), or you can combine them and transform the object in one step. If you have a lot of repetitive movement going on in your game it’s worth learning more about <a href="../../jme3/matrix.html" class="page">Matrix4f</a> for optimization. JME can also help you interpolate the steps between two fixed transformations.</p>
- </div>
- <div class="ulist">
- <ul>
- <li>
- <p>com.jme3.math.Transform, interpolateTransforms() – interpolate a step between two transformations</p>
- <div class="ulist">
- <ul>
- <li>
- <p><a href="https://javadoc.jmonkeyengine.org/v3.3.2-stable/com/jme3/math/Transform.html">com.jme.math.Transform</a></p>
- </li>
- </ul>
- </div>
- </li>
- <li>
- <p>In case you missed it, see also <a href="../../jme3/quaternion.html" class="page">quaternion</a>.</p>
- </li>
- </ul>
- </div>
- </div>
- </div>
- <nav class="pagination">
- <span class="prev"><a href="math_cheet_sheet.html">3D math "cheat sheet"</a></span>
- <span class="next"><a href="math_video_tutorials.html">Math video tutorial series</a></span>
- </nav>
- </article>
- <aside class="toc sidebar" data-title="Contents" data-levels="2">
- <div class="toc-menu"></div>
- </aside>
- </div>
- </main>
- </div>
- <footer class="footer">
- <p>Copyright 2020 jMonkeyEngine Wiki Contributors. Licensed BSD-3.</p>
- </footer>
- <script src="../../../_/js/vendor/docsearch.min.js"></script>
- <!-- fetched from https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js -->
- <script>
- var search = docsearch({
- apiKey: 'a736b6d93de805e26ec2f49b55013fbd',
- indexName: 'jmonkeyengine',
- inputSelector: '#search-input',
- autocompleteOptions: { hint: false, keyboardShortcuts: ['s'] },
- algoliaOptions: { hitsPerPage: 10 }
- }).autocomplete
- search.on('autocomplete:closed', function () { search.autocomplete.setVal() })
- function focusSearchInput () { document.querySelector('#search-input').focus() }
- if (document.querySelector('.home-link.is-current')) window.addEventListener('load', focusSearchInput)
- </script>
- <script src="../../../_/js/site.js"></script>
- <script async src="../../../_/js/vendor/highlight.js"></script>
- </body>
- </html>
|