LearnOpenGL

Translation in progress of learnopengl.com.
git clone https://git.mtkn.jp/LearnOpenGL
Log | Files | Refs

Camera.html (70625B)


      1 <!DOCTYPE html>
      2 <html lang="ja"> 
      3 <head>
      4     <meta charset="utf-8"/>
      5     <title>LearnOpenGL</title>
      6     <link rel="shortcut icon" type="image/ico" href="/favicon.ico"  />
      7 	<link rel="stylesheet" href="../static/style.css" />
      8 	<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"> </script>
      9 	<script src="/static/functions.js"></script>
     10 </head>
     11 <body>
     12 	<nav>
     13 <ol>
     14 	<li id="Introduction">
     15 		<a href="https://learnopengl.com/Introduction">はじめに</a>
     16 	</li>
     17 	<li id="Getting-started">
     18 		<span class="closed">入門</span>
     19 		<ol>
     20 			<li id="Getting-started/OpenGL">
     21 				<a href="https://learnopengl.com/Getting-started/OpenGL">OpenGL </a>
     22 			</li>
     23 			<li id="Getting-started/Creating-a-window">
     24 				<a href="https://learnopengl.com/Getting-started/Creating-a-window">ウィンドウの作成</a>
     25 			</li>
     26 			<li id="Getting-started/Hello-Window">
     27 				<a href="https://learnopengl.com/Getting-started/Hello-Window">最初のウィンドウ</a>
     28 			</li>
     29 			<li id="Getting-started/Hello-Triangle">
     30 				<a href="https://learnopengl.com/Getting-started/Hello-Triangle">最初の三角形</a>
     31 			</li>
     32 			<li id="Getting-started/Shaders">
     33 				<a href="https://learnopengl.com/Getting-started/Shaders">シェーダー</a>
     34 			</li>
     35 			<li id="Getting-started/Textures">
     36 				<a href="https://learnopengl.com/Getting-started/Textures">テクスチャ</a>
     37 			</li>
     38 			<li id="Getting-started/Transformations">
     39 				<a href="https://learnopengl.com/Getting-started/Transformations">座標変換</a>
     40 			</li>
     41 			<li id="Getting-started/Coordinate-Systems">
     42 				<a href="https://learnopengl.com/Getting-started/Coordinate-Systems">座標系</a>
     43 			</li>
     44 			<li id="Getting-started/Camera">
     45 				<a href="https://learnopengl.com/Getting-started/Camera">カメラ</a>
     46 			</li>
     47 			<li id="Getting-started/Review">
     48 				<a href="https://learnopengl.com/Getting-started/Review">まとめ</a>
     49 			</li>
     50 		</ol>
     51 	</li>
     52 	<li id="Lighting">
     53 		<span class="closed">Lighting </span>
     54 		<ol>
     55 			<li id="Lighting/Colors">
     56 				<a href="https://learnopengl.com/Lighting/Colors">Colors </a>
     57 			</li>
     58 			<li id="Lighting/Basic-Lighting">
     59 				<a href="https://learnopengl.com/Lighting/Basic-Lighting">Basic Lighting </a>
     60 			</li>
     61 			<li id="Lighting/Materials">
     62 				<a href="https://learnopengl.com/Lighting/Materials">Materials </a>
     63 			</li>
     64 			<li id="Lighting/Lighting-maps">
     65 				<a href="https://learnopengl.com/Lighting/Lighting-maps">Lighting maps </a>
     66 			</li>
     67 			<li id="Lighting/Light-casters">
     68 				<a href="https://learnopengl.com/Lighting/Light-casters">Light casters </a>
     69 			</li>
     70 			<li id="Lighting/Multiple-lights">
     71 				<a href="https://learnopengl.com/Lighting/Multiple-lights">Multiple lights </a>
     72 			</li>
     73 			<li id="Lighting/Review">
     74 				<a href="https://learnopengl.com/Lighting/Review">Review </a>
     75 			</li>
     76 		</ol>
     77 	</li>
     78 	<li id="Model-Loading">
     79 		<span class="closed">Model Loading </span>
     80 		<ol>
     81 			<li id="Model-Loading/Assimp">
     82 				<a href="https://learnopengl.com/Model-Loading/Assimp">Assimp </a>
     83 			</li>
     84 			<li id="Model-Loading/Mesh">
     85 				<a href="https://learnopengl.com/Model-Loading/Mesh">Mesh </a>
     86 			</li>
     87 			<li id="Model-Loading/Model">
     88 				<a href="https://learnopengl.com/Model-Loading/Model">Model </a>
     89 			</li>
     90 		</ol>
     91 	</li>
     92 	<li id="Advanced-OpenGL">
     93 		<span class="closed">Advanced OpenGL </span>
     94 		<ol>
     95 			<li id="Advanced-OpenGL/Depth-testing">
     96 				<a href="https://learnopengl.com/Advanced-OpenGL/Depth-testing">Depth testing </a>
     97 			</li>
     98 			<li id="Advanced-OpenGL/Stencil-testing">
     99 				<a href="https://learnopengl.com/Advanced-OpenGL/Stencil-testing">Stencil testing </a>
    100 			</li>
    101 			<li id="Advanced-OpenGL/Blending">
    102 				<a href="https://learnopengl.com/Advanced-OpenGL/Blending">Blending </a>
    103 			</li>
    104 			<li id="Advanced-OpenGL/Face-culling">
    105 				<a href="https://learnopengl.cm/Advanced-OpenGL/Face-culling">Face culling </a>
    106 			</li>
    107 			<li id="Advanced-OpenGL/Framebuffers">
    108 				<a href="https://learnopengl.com/Advanced-OpenGL/Framebuffers">Framebuffers </a>
    109 			</li>
    110 			<li id="Advanced-OpenGL/Cubemaps">
    111 				<a href="https://learnopengl.com/Advanced-OpenGL/Cubemaps">Cubemaps </a>
    112 			</li>
    113 			<li id="Advanced-OpenGL/Advanced-Data">
    114 				<a href="https://learnopengl.com/Advanced-OpenGL/Advanced-Data">Advanced Data </a>
    115 			</li>
    116 			<li id="Advanced-OpenGL/Advanced-GLSL">
    117 				<a href="https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL">Advanced GLSL </a>
    118 			</li>
    119 			<li id="Advanced-OpenGL/Geometry-Shader">
    120 				<a href="https://learnopengl.com/Advanced-OpenGL/Geometry-Shader">Geometry Shader </a>
    121 			</li>
    122 			<li id="Advanced-OpenGL/Instancing">
    123 				<a href="https://learnopengl.com/Advanced-OpenGL/Instancing">Instancing </a>
    124 			</li>
    125 			<li id="Advanced-OpenGL/Anti-Aliasing">
    126 				<a href="https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing">Anti Aliasing </a>
    127 			</li>
    128 		</ol>
    129 	</li>
    130 	<li id="Advanced-Lighting">
    131 		<span class="closed">Advanced Lighting </span>
    132 		<ol>
    133 			<li id="Advanced-Lighting/Advanced-Lighting">
    134 				<a href="https://learnopengl.com/Advanced-Lighting/Advanced-Lighting">Advanced Lighting </a>
    135 			</li>
    136 			<li id="Advanced-Lighting/Gamma-Correction">
    137 				<a href="https://learnopengl.com/Advanced-Lighting/Gamma-Correction">Gamma Correction </a>
    138 			</li>
    139 			<li id="Advanced-Lighting/Shadows">
    140 				<span class="closed">Shadows </span>
    141 				<ol>
    142 					<li id="Advanced-Lighting/Shadows/Shadow-Mapping">
    143 						<a href="https://learnopengl.com/Advanced-Lighting/Shadows/Shadow-Mapping">Shadow Mapping </a>
    144 					</li>
    145 					<li id="Advanced-Lighting/Shadows/Point-Shadows">
    146 						<a href="https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows">Point Shadows </a>
    147 					</li>
    148 				</ol>
    149 			</li>
    150 			<li id="Advanced-Lighting/Normal-Mapping">
    151 				<a href="https://learnopengl.com/Advanced-Lighting/Normal-Mapping">Normal Mapping </a>
    152 			</li>
    153 			<li id="Advanced-Lighting/Parallax-Mapping">
    154 				<a href="https://learnopengl.com/Advanced-Lighting/Parallax-Mapping">Parallax Mapping </a>
    155 			</li>
    156 			<li id="Advanced-Lighting/HDR">
    157 				<a href="https://learnopengl.com/Advanced-Lighting/HDR">HDR </a>
    158 			</li>
    159 			<li id="Advanced-Lighting/Bloom">
    160 				<a href="https://learnopengl.com/Advanced-Lighting/Bloom">Bloom </a>
    161 			</li>
    162 			<li id="Advanced-Lighting/Deferred-Shading">
    163 				<a href="https://learnopengl.com/Advanced-Lighting/Deferred-Shading">Deferred Shading </a>
    164 			</li>
    165 			<li id="Advanced-Lighting/SSAO">
    166 				<a href="https://learnopengl.com/Advanced-Lighting/SSAO">SSAO </a>
    167 			</li>
    168 		</ol>
    169 	</li>
    170 	<li id="PBR">
    171 		<span class="closed">PBR </span>
    172 		<ol>
    173 			<li id="PBR/Theory">
    174 				<a href="https://learnopengl.com/PBR/Theory">Theory </a>
    175 			</li>
    176 			<li id="PBR/Lighting">
    177 				<a href="https://learnopengl.com/PBR/Lighting">Lighting </a>
    178 			</li>
    179 			<li id="PBR/IBL">
    180 				<span class="closed">IBL </span>
    181 				<ol>
    182 					<li id="PBR/IBL/Diffuse-irradiance">
    183 						<a href="https://learnopengl.com/PBR/IBL/Diffuse-irradiance">Diffuse irradiance </a>
    184 					</li>
    185 					<li id="PBR/IBL/Specular-IBL">
    186 						<a href="https://learnopengl.com/PBR/IBL/Specular-IBL">Specular IBL </a>
    187 					</li>
    188 				</ol>
    189 			</li>
    190 		</ol>
    191 	</li>
    192 	<li id="In-Practice">
    193 		<span class="closed">In Practice </span>
    194 		<ol>
    195 			<li id="In-Practice/Debugging">
    196 				<a href="https://learnopengl.com/In-Practice/Debugging">Debugging </a>
    197 			</li>
    198 			<li id="In-Practice/Text-Rendering">
    199 				<a href="https://learnopengl.com/In-Practice/Text-Rendering">Text Rendering </a>
    200 			</li>
    201 			<li id="In-Practice/2D-Game">
    202 				<span class="closed">2D Game </span>
    203 				<ol>
    204 					<li id="In-Practice/2D-Game/Breakout">
    205 						<a href="https://learnopengl.com/In-Practice/2D-Game/Breakout">Breakout </a>
    206 					</li>
    207 					<li id="In-Practice/2D-Game/Setting-up">
    208 						<a href="https://learnopengl.com/In-Practice/2D-Game/Setting-up">Setting up </a>
    209 					</li>
    210 					<li id="In-Practice/2D-Game/Rendering-Sprites">
    211 						<a href="https://learnopengl.com/In-Practice/2D-Game/Rendering-Sprites">Rendering Sprites </a>
    212 					</li>
    213 					<li id="In-Practice/2D-Game/Levels">
    214 						<a href="https://learnopengl.com/In-Practice/2D-Game/Levels">Levels </a>
    215 					</li>
    216 					<li id="In-Practice/2D-Game/Collisions">
    217 						<span class="closed">Collisions </span>
    218 						<ol>
    219 							<li id="In-Practice/2D-Game/Collisions/Ball">
    220 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Ball">Ball </a>
    221 							</li>
    222 							<li id="In-Practice/2D-Game/Collisions/Collision-detection">
    223 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-detection">Collision detection </a>
    224 							</li>
    225 							<li id="In-Practice/2D-Game/Collisions/Collision-resolution">
    226 								<a href="https://learnopengl.com/In-Practice/2D-Game/Collisions/Collision-resolution">Collision resolution </a>
    227 							</li>
    228 						</ol>
    229 					</li>
    230 					<li id="In-Practice/2D-Game/Particles">
    231 						<a href="https://learnopengl.com/In-Practice/2D-Game/Particles">Particles </a>
    232 					</li>
    233 					<li id="In-Practice/2D-Game/Postprocessing">
    234 						<a href="https://learnopengl.com/In-Practice/2D-Game/Postprocessing">Postprocessing </a>
    235 					</li>
    236 					<li id="In-Practice/2D-Game/Powerups">
    237 						<a href="https://learnopengl.com/In-Practice/2D-Game/Powerups">Powerups </a>
    238 					</li>
    239 					<li id="In-Practice/2D-Game/Audio">
    240 						<a href="https://learnopengl.com/In-Practice/2D-Game/Audio">Audio </a>
    241 					</li>
    242 					<li id="In-Practice/2D-Game/Render-text">
    243 						<a href="https://learnopengl.com/In-Practice/2D-Game/Render-text">Render text </a>
    244 					</li>
    245 					<li id="In-Practice/2D-Game/Final-thoughts">
    246 						<a href="https://learnopengl.com/In-Practice/2D-Game/Final-thoughts">Final thoughts </a>
    247 					</li>
    248 				</ol>
    249 			</li>
    250 		</ol>
    251 	</li>
    252 	<li id="Guest-Articles">
    253 		<span class="closed">Guest Articles </span>
    254 		<ol>
    255 			<li id="Guest-Articles/How-to-publish">
    256 				<a href="https://learnopengl.com/Guest-Articles/How-to-publish">How to publish </a>
    257 			</li>
    258 			<li id="Guest-Articles/2020">
    259 				<span class="closed">2020 </span>
    260 				<ol>
    261 					<li id="Guest-Articles/2020/OIT">
    262 						<span class="closed">OIT </span>
    263 						<ol>
    264 							<li id="Guest-Articles/2020/OIT/Introduction">
    265 								<a href="https://learnopengl.com/Guest-Articles/2020/OIT/Introduction">Introduction </a>
    266 							</li>
    267 							<li id="Guest-Articles/2020/OIT/Weighted-Blended">
    268 								<a href="https://learnopengl.com/Guest-Articles/2020/OIT/Weighted-Blended">Weighted Blended </a>
    269 							</li>
    270 						</ol>
    271 					</li>
    272 					<li id="Guest-Articles/2020/Skeletal-Animation">
    273 						<a href="https://learnopengl.com/Guest-Articles/2020/Skeletal-Animation">Skeletal Animation </a>
    274 					</li>
    275 				</ol>
    276 			</li>
    277 			<li id="Guest-Articles/2021">
    278 				<span class="closed">2021 </span>
    279 				<ol>
    280 					<li id="Guest-Articles/2021/CSM">
    281 						<a href="https://learnopengl.com/Guest-Articles/2021/CSM">CSM </a>
    282 					</li>
    283 					<li id="Guest-Articles/2021/Scene">
    284 						<span class="closed">Scene </span>
    285 						<ol>
    286 							<li id="Guest-Articles/2021/Scene/Scene-Graph">
    287 								<a href="https://learnopengl.com/Guest-Articles/2021/Scene/Scene-Graph">Scene Graph </a>
    288 							</li>
    289 							<li id="Guest-Articles/2021/Scene/Frustum-Culling">
    290 								<a href="https://learnopengl.com/Guest-Articles/2021/Scene/Frustum-Culling">Frustum Culling </a>
    291 							</li>
    292 						</ol>
    293 					</li>
    294 					<li id="Guest-Articles/2021/Tessellation">
    295 						<span class="closed">Tessellation </span>
    296 						<ol>
    297 							<li id="Guest-Articles/2021/Tessellation/Height-map">
    298 								<a href="https://learnopengl.com/Guest-Articles/2021/Tessellation/Height-map">Height map </a>
    299 							</li>
    300 						</ol>
    301 					</li>
    302 				</ol>
    303 			</li>
    304 		</ol>
    305 	</li>
    306 	<li id="Code-repository">
    307 		<a href="https://learnopengl.com/Code-repository">Code repository </a>
    308 	</li>
    309 	<li id="Translations">
    310 		<a href="https://learnopengl.com/Translations">Translations </a>
    311 	</li>
    312 	<li id="About">
    313 		<a href="https://learnopengl.com/About">About </a>
    314 	</li>
    315 </ol>
    316 	</nav>
    317 	<main>
    318     <h1 id="content-title">Camera</h1>
    319     <h1 id="content-title">カメラ</h1>
    320 <h1 id="content-url" style='display:none;'>Getting-started/Camera</h1>
    321 <p>
    322   In the previous chapter we discussed the view matrix and how we can use the view matrix to move around the scene (we moved backwards a little). OpenGL by itself is not familiar with the concept of a <em>camera</em>, but we can try to simulate one by moving all objects in the scene in the reverse direction, giving the illusion that <strong>we</strong> are moving.
    323   前章において視野行列を用いて空間上を移動する方法を学びました(少しだけ後ろに下りました)。OpenGL自体にカメラの概念はありませんが、空間中の全ての物体を反対方向に動かすことでカメラを再現でき、<strong>自分自身</strong>が動いているように見せかけることができます。
    324 </p>
    325 
    326 <p>
    327   In this chapter we'll discuss how we can set up a camera in OpenGL. We will discuss a fly style camera that allows you to freely move around in a 3D scene. We'll also discuss keyboard and mouse input and finish with a custom camera class.
    328   本章ではどのようにしてカメラを設定するかを見て行きます。ここでは3次元空間上を自由に動き回れるような飛行型のカメラについて議論します。キーボードやマウスからの入力についても議論し、最後に独自のカメラクラスを作成します。
    329 </p>
    330 
    331 <h2>Camera/View space</h2>
    332 <h2>カメラ空間(視野空間)</h2>
    333 <p>
    334   When we're talking about camera/view space we're talking about all the vertex coordinates as seen from the camera's perspective as the origin of the scene: the view matrix transforms all the world coordinates into view coordinates that are relative to the camera's position and direction. To define a camera we need its position in world space, the direction it's looking at, a vector pointing to the right and a vector pointing upwards from the camera. A careful reader may notice that we're actually going to create a coordinate system with 3 perpendicular unit axes with the camera's position as the origin.
    335   カメラ空間あるいは視野空間というのは全ての頂点の座標がカメラの位置を原点とし、カメラから見ているような空間です。視野行列が世界全体の座標を視野座標に変換します。この視野座標がカメラの位置と向いている方向に対する座標です。カメラを定義する為には大域空間におけるカメラの位置、向いている方向、カメラの右側を指すベクトル、そしてカメラの上側を指すベクトルが必要です。注意深い読者は、3つの互いに直交する単位ベクトルを用いてカメラの位置を原点とした座標空間を作成しようとしていることに気付くでしょう。
    336 </p>
    337 
    338 <img src="/img/getting-started/camera_axes.png" class="clean"/>
    339 
    340 <h3>1. Camera position</h3>
    341 <h3>1. カメラの位置</h3>
    342 <p>
    343   Getting the camera position is easy. The camera position is a vector in world space that points to the camera's position. We set the camera at the same position we've set the camera in the previous chapter:
    344   カメラの位置を取得するのは簡単です。カメラの位置は大域空間におけるカメラの位置を表わすベクトルです。今回カメラの位置は前章で設定したものと同じにしましょう:
    345 </p>
    346 
    347 <pre><code>
    348 glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);  
    349 </code></pre>
    350 
    351 <note>
    352   Don't forget that the positive z-axis is going through your screen towards you so if we want the camera to move backwards, we move along the positive z-axis.
    353   z軸は画面の手前に伸びているので、カメラを手前に動かす場合、z軸正の方向を指定します。
    354 </note>
    355 
    356 <h3>2. Camera direction</h3>
    357 <h2>2. カメラの方向</h2>
    358 <p>
    359   The next vector required is the camera's direction e.g. at what direction it is pointing at. For now we let the camera point to the origin of our scene: <code>(0,0,0)</code>. Remember that if we subtract two vectors from each other we get a vector that's the difference of these two vectors? Subtracting the camera position vector from the scene's origin vector thus results in the direction vector we want. For the view matrix's coordinate system we want its z-axis to be positive and because by convention (in OpenGL) the camera points towards the negative z-axis we want to negate the direction vector. If we switch the subtraction order around we now get a vector pointing towards the camera's positive z-axis:
    360   次に必要なのはカメラの向き、つまりカメラがどの点を見ているかです。とりあえずカメラが原点<code>(0, 0, 0)</code>を見ているとしましょう。ベクトルの引き算により、それらのベクトルの差が得られるのを覚えているでしょうか。カメラの位置を世界の原点から引き算すれば、カメラの向きを表わすベクトルが得られます。視野行列の座標系においてカメラの位置のz座標は正で、OpenGLの慣例によりカメラはz軸の負の方を向いているので、方向ベクトルの正負を反転させます。引き算の順序を反対にした場合、原点からカメラを向いた、z座標が正のベクトルが得られます:
    361 </p>
    362 
    363 <pre><code>
    364 glm::vec3 cameraTarget = glm::vec3(0.0f, 0.0f, 0.0f);
    365 glm::vec3 cameraDirection = glm::normalize(cameraPos - cameraTarget);
    366 </code></pre>
    367 
    368 <warning>
    369   The name <em>direction</em> vector is not the best chosen name, since it is actually pointing in the reverse direction of what it is targeting.
    370   <em>direction(方向)</em>というのは最良の名前とは言えません。このベクトルは実際にはカメラの向いているのと逆方向のベクトルだからです。
    371 </warning>
    372 
    373 <h3>3. Right axis</h3>
    374 <h3>3. 右方向の軸</h3>
    375 <p>
    376   The next vector that we need is a <em>right</em> vector that represents the positive x-axis of the camera space. To get the <em>right</em> vector we use a little trick by first specifying an <em>up</em> vector that points upwards (in world space). Then we do a cross product on the up vector and the direction vector from step 2. Since the result of a cross product is a vector perpendicular to both vectors, we will get a vector that points in the positive x-axis's direction (if we would switch the cross product order we'd get a vector that points in the negative x-axis): 
    377   次に必要なベクトルは<em>右方向</em>のベクトルです。このベクトルはカメラ空間のx軸正の方向を表わすものです。<em>右方向</em>のベクトルを得る為に少し技巧的なことをします。まず大域空間において<em>上向き</em>のベクトルを取り、このベクトルと、2段階目に作成した方向ベクトルの外積を取ります。外積の結果得られるベクトルは両方のベクトルに直交するので、この計算によりx軸正の方向を向いたベクトルが得られるのです(外積の掛ける順番を逆にするとベクトルはx軸負の方向を向きます)。
    378 </p>
    379 
    380 <pre><code>
    381 glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f); 
    382 glm::vec3 cameraRight = glm::normalize(<function id='61'>glm::cross</function>(up, cameraDirection));
    383 </code></pre>
    384 
    385 <h3>4. Up axis</h3>
    386 <h3>4. 上方向の軸</h3>
    387 <p>
    388   Now that we have both the x-axis vector and the z-axis vector, retrieving the vector that points to the camera's positive y-axis is relatively easy: we take the cross product of the right and direction vector:
    389   ここまででx軸とz軸のベクトルが得られたので、カメラの座標系におけるy軸正の方向のベクトルを計算するのは簡単です。右方向のベクトルとカメラの向いている方向のベクトルの外積を取ればいいのです:
    390 </p>
    391 
    392 <pre><code>
    393 glm::vec3 cameraUp = <function id='61'>glm::cross</function>(cameraDirection, cameraRight);
    394 </code></pre>
    395 
    396 <p>
    397 	With the help of the cross product and a few tricks we were able to create all the vectors that form the view/camera space. For the more mathematically inclined readers, this process is known as the <a href="http://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process" target="_blank">Gram-Schmidt</a> process in linear algebra. Using these camera vectors we can now create a <def>LookAt</def> matrix that proves very useful for creating a camera.
    398 	外積により視野空間を形成するベクトルを全て取得できました。この手法は<a href="http://en.wikipedia.org/wiki/Gram%E2%80%93Schmidt_process" target="_blank">グラム・シュミットの正規直交化法</a>と言います。数学に傾倒した人はご自身で調べてみて下さい。これらのカメラに関するベクトルを利用することで、<def>視点行列(LookAt Matrix)</def>を作成できます。この行列はカメラを作成する上で非常に便利なものです。
    399 </p>
    400 
    401 <h2>Look At</h2>
    402 <h2>視点</h2>
    403 <p>
    404   A great thing about matrices is that if you define a coordinate space using 3 perpendicular (or non-linear) axes you can create a matrix with those 3 axes plus a translation vector and you can  transform any vector to that coordinate space by multiplying it with this matrix. This is exactly what the <em>LookAt</em> matrix does and now that we have 3 perpendicular axes and a position vector to define the camera space we can create our own LookAt matrix:
    405   互いに直交する(あるいは一次独立な)3つのベクトルにより座標空間を定義し、その3つの座標軸と平行移動ベクトルを用いると、任意のベクトルにその変換行列を掛けることで、その座標空間に変換できます。これはまさに<em>視点</em>行列が行なうことです。先程カメラ空間を定義する為に3つの直交するベクトルとカメラの位置ベクトルを作成しました。これらを用いて以下のように視点行列を作成できます:
    406   
    407   \[LookAt = \begin{bmatrix} \color{red}{R_x} & \color{red}{R_y} & \color{red}{R_z} & 0 \\ \color{green}{U_x} & \color{green}{U_y} & \color{green}{U_z} & 0 \\ \color{blue}{D_x} & \color{blue}{D_y} & \color{blue}{D_z} & 0 \\ 0 & 0 & 0  & 1 \end{bmatrix} * \begin{bmatrix} 1 & 0 & 0 & -\color{purple}{P_x} \\ 0 & 1 & 0 & -\color{purple}{P_y} \\ 0 & 0 & 1 & -\color{purple}{P_z} \\ 0 & 0 & 0  & 1 \end{bmatrix} \]
    408   
    409   Where \({\color{red}R}\) is the right vector, \({\color{green}U}\) is the up vector, \({\color{blue}D}\) is the direction vector and \({\color{purple}P}\) is the camera's position vector. Note that the rotation (left matrix) and translation (right matrix) parts are inverted (transposed and negated respectively) since we want to rotate and translate the world in the opposite direction of where we want the camera to move. Using this LookAt matrix as our view matrix effectively transforms all the world coordinates to the view space we just defined. The LookAt matrix then does exactly what it says: it creates a view matrix that <em>looks</em> at a given target.
    410   ここで、\({\color{red}R}\)はカメラの右方向のベクトル、\({\color{green}U}\)は上方向のベクトル、\({\color{blue}D}\)はカメラの方向ベクトル、そして\({\color{purple}P}\)はカメラの位置ベクトルです。左側の行列の回転と、右側の行列の平行移動がそれぞれ逆向きになっていることに注意して下さい。転置行列による回転と、符号が反転した平行移動にそれぞれなっています。カメラを移動させるのと反対方向に世界全体を回転、平行移動する為です。この視点行列を視野行列として用いることで、大域座標全体を今しがた定義した視野空間に変換できます。視点行列は与えられた位置を<em>見る</em>ような視野行列を作成します。視点行列は名前の通りの仕事をするのです。
    411 </p>
    412 
    413 <p>
    414   Luckily for us, GLM already does all this work for us. We only have to specify a camera position, a target position and a vector that represents the up vector in world space (the up vector we used for calculating the right vector). GLM then creates the LookAt matrix that we can use as our view matrix:
    415   有り難いことにGLMが必要な仕事を全て行ってくれます。カメラの位置、視点の位置そして大域空間の上を示すベクトル(カメラの右を示すベクトルを作成するのに必要です)を指定するだけでいいのです。そうすると視野行列の作成に必要な視点行列をGLMが作成してくれます:
    416 </p>
    417 
    418 <pre><code>
    419 glm::mat4 view;
    420 view = <function id='62'>glm::lookAt</function>(glm::vec3(0.0f, 0.0f, 3.0f), 
    421   		   glm::vec3(0.0f, 0.0f, 0.0f), 
    422   		   glm::vec3(0.0f, 1.0f, 0.0f));
    423 </code></pre>
    424 
    425 <p>
    426   The <fun><function id='62'>glm::LookAt</function></fun> function requires a position, target and up vector respectively. This example creates a view matrix that is the same as the one we created in the previous chapter.
    427 <fun><function id='62'>glm::LookAt</function></fun>には位置、視点、上のベクトルを渡します。この例では前章で作成したものと同じ視野行列を作成しています。
    428 </p>
    429 
    430 <p>
    431   Before delving into user input, let's get a little funky first by rotating the camera around our scene. We keep the target of the scene at <code>(0,0,0)</code>. We use a little bit of trigonometry to create an <code>x</code> and <code>z</code> coordinate each frame that represents a point on a circle and we'll use these for our camera position. By re-calculating the <code>x</code> and <code>y</code> coordinate over time we're traversing all the points in a circle and thus the camera rotates around the scene. We enlarge this circle by a pre-defined <var>radius</var> and create a new view matrix each frame using GLFW's <fun><function id='47'>glfwGetTime</function></fun> function:
    432   ユーザーからの入力に話を進める前に、少しイケたことをしてみましょう。カメラの視点を<code>(0, 0, 0)</code>に固定して、その周りで回転させてみます。三角関数を利用して各フレームに対してxz平面における円周上の点を求め、それをカメラの位置として利用します。<code>x</code>座標と<code>z</code>座標をフレーム毎に計算しなおすことで円周上をカメラが移動して行き、回転しているように見えます。あらかじめ定義しておいた<var>radius</var>という変数を用いてこの円周を大きくし、<fun><function id='47'>glfwGetTime</function></fun>を用いてフレーム毎に新しい視野行列を作成します:
    433 </p>
    434 
    435 <pre><code>
    436 const float radius = 10.0f;
    437 float camX = sin(<function id='47'>glfwGetTime</function>()) * radius;
    438 float camZ = cos(<function id='47'>glfwGetTime</function>()) * radius;
    439 glm::mat4 view;
    440 view = <function id='62'>glm::lookAt</function>(glm::vec3(camX, 0.0, camZ), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));  
    441 </code></pre>
    442 
    443 <p>
    444   If you run this code you should get something like this:
    445   このコードを実行すると以下のようなものが得られます:
    446 </p>
    447 
    448 <div class="video paused" onclick="ClickVideo(this)">
    449   <video width="600" height="450" loop>
    450     <source src="/video/getting-started/camera_circle.mp4" type="video/mp4"/>
    451     <img src="/img/getting-started/camera_circle.png" class="clean"/>
    452   </video>
    453 </div>
    454 
    455 <p>
    456   With this little snippet of code the camera now circles around the scene over time. Feel free to experiment with the radius and position/direction parameters to get the feel of how this <em>LookAt</em> matrix works. Also, check the  <a href="/code_viewer_gh.php?code=src/1.getting_started/7.1.camera_circle/camera_circle.cpp" target="_blank">source code</a> if you're stuck.
    457   このちょっとしたコードで、時間と共にカメラを回転させることができました。半径や位置、方向等の変数を変化させてみて下さい。<em>視点行列</em>の働きが掴めるはずです。また、どこかで詰まった場合は<a href="/code_viewer_gh.php?code=src/1.getting_started/7.1.camera_circle/camera_circle.cpp" target="_blank">ソースコード</a>を確認して下さい。
    458 </p>
    459 
    460 <h1>Walk around</h1>
    461 <h1>歩き回る</h1>
    462 <p>
    463   Swinging the camera around a scene is fun, but it's more fun to do all the movement ourselves! First we need to set up a camera system, so it is useful to define some camera variables at the top of our program:
    464   カメラが動くのは楽しいものですが、それを自分自身で行なえたらもっと楽しいでしょう。まずカメラの座標系を設定しなければなりませんが、その為にカメラに関する変数をいくつかプログラムの冒頭に定義しておくのが便利です:
    465 </p>
    466 
    467 <pre><code>
    468 glm::vec3 cameraPos   = glm::vec3(0.0f, 0.0f,  3.0f);
    469 glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
    470 glm::vec3 cameraUp    = glm::vec3(0.0f, 1.0f,  0.0f);
    471 </code></pre>
    472 
    473 <p>
    474   The <code>LookAt</code> function now becomes:
    475   これらを用いると<code>LookAt</code>関数は以下のようになります:
    476 </p>
    477 
    478 <pre><code>
    479 view = <function id='62'>glm::lookAt</function>(cameraPos, cameraPos + cameraFront, cameraUp);
    480 </code></pre>
    481 
    482 <p>
    483   First we set the camera position to the previously defined <var>cameraPos</var>. The direction is the current position + the direction vector we just defined. This ensures that however we move, the camera keeps looking at the target direction. Let's play a bit with these variables by updating the <var>cameraPos</var> vector when we press some keys.
    484   まず初めに先程定義した<var>cameraPos</var>を用いてカメラの位置を設定します。方向は現在の位置ベクトルにカメラの方向ベクトルを足したものです。こうすることでカメラがどのように動いても同じ点を見続けるようになります。これを少し面白くするために、特定のキーを押下した時に<var>cameraPos</var>を変更するようにしてみましょう:
    485 </p>
    486 
    487 <p>
    488   We already defined a <fun>processInput</fun> function to manage GLFW's keyboard input so let's add a few extra key commands:
    489   GLFWのキーボーッド入力を処理する為に<fun>processInput</fun>という関数を既に定義していました。これに他のキーの処理を追加します:
    490 </p>
    491 
    492 <pre><code>
    493 void processInput(GLFWwindow *window)
    494 {
    495     ...
    496     const float cameraSpeed = 0.05f; // adjust accordingly
    497     if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
    498         cameraPos += cameraSpeed * cameraFront;
    499     if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
    500         cameraPos -= cameraSpeed * cameraFront;
    501     if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
    502         cameraPos -= glm::normalize(<function id='61'>glm::cross</function>(cameraFront, cameraUp)) * cameraSpeed;
    503     if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
    504         cameraPos += glm::normalize(<function id='61'>glm::cross</function>(cameraFront, cameraUp)) * cameraSpeed;
    505 }
    506 </code></pre>
    507 
    508 <p>
    509   Whenever we press one of the <code>WASD</code> keys, the camera's position is updated accordingly. If we want to move forward or backwards we add or subtract the direction vector from the position vector scaled by some speed value. If we want to move sideways we do a cross product to create a <em>right</em> vector and we move along the right vector accordingly. This creates the familiar <def>strafe</def> effect when using the camera. 
    510   <code>WASD</code>のいずれかのキーを押すと、押したキーに応じてカメラの位置が更新されます。前進あるいは後退したい時はカメラの向きのベクトルに速度の値を掛けたものをカメラの位置ベクトルに加え、あるいは引きます。横に移動したければ外積を取って<em>右方向</em>のベクトルを作り、その方向に移動します。この処理により、<def>機銃掃射(strafe)</def>効果が得られます。これは一点を見つめたまま横に移動するというもののようです。
    511 </p>
    512 
    513 <note>
    514   Note that we normalize the resulting <em>right</em> vector. If we wouldn't normalize this vector, the resulting cross product may return differently sized vectors based on the <var>cameraFront</var> variable. If we would not normalize the vector we would move slow or fast based on the camera's orientation instead of at a consistent movement speed.
    515   <em>右方向</em>のベクトルを正規化していることに注意して下さい。こうしないと外積の結果得られるベクトルの大きさが違ってしまします。カメラの向きによって移動速度が大きくなったり小さくなったりして一定しません。
    516 </note>
    517 
    518 <p>
    519   By now, you should already be able to move the camera somewhat, albeit at a speed that's system-specific so you may need to adjust <var>cameraSpeed</var>.
    520   ここまでで既にカメラを移動することはできるようになりました。とは言えその速度はシステムによって異なりますので、<var>cameraSpeed</var>を調整しないといけません。
    521 </p>
    522 
    523 <h2>Movement speed</h2>
    524 <h2>移動速度</h2>
    525 <p>
    526   Currently we used a constant value for movement speed when walking around. In theory this seems fine, but in practice people's machines have different processing powers and the result of that is that some people are able to render much more frames than others each second. Whenever a user renders more frames than another user he also calls <fun>processInput</fun> more often. The result is that some people move really fast and some really slow depending on their setup. When shipping your application you want to make sure it runs the same on all kinds of hardware.
    527   現状移動速度は定数です。これでも良いように思われますが、実際はコンピュータの処理能力により1秒間に描画できるフレーム数が異なり、多くのフレームを描画できるコンピュータではそれだけ多く<fun>processInput</fun>が呼ばれるので、移動速度がコンピュータによりまちまちになってしまいます。アプリケーションを配布するなら、どのようなハードウェアにおいても同じように実行されるのが好ましいでしょう。
    528 </p>
    529 
    530 <p>
    531   Graphics applications and games usually keep track of a <def>deltatime</def> variable that stores the time it took to render the last frame. We then multiply all velocities with this <var>deltaTime</var> value. The result is that when we have a large <var>deltaTime</var> in a frame, meaning that the last frame took longer than average, the velocity for that frame will also be a bit higher to balance it all out. When using this approach it does not matter if you have a very fast or slow pc, the velocity of the camera will be balanced out accordingly so each user will have the same experience.
    532   グラフィックスを利用するアプリケーションやゲームは、通常直前のフレームの描画にかかった時間である<def>差分時間(deltatime)</def>という変数を追跡しています。ここではこの<var>deltaTime</var>の値を速度に掛け合せます。そうすることで直前のフレームの描画に長い時間かかり、<var>deltaTime</var>が大きくなった場合、そのフレームでの速度も大きくなり、描画時間の差が均されます。この方法によりPCの処理速度に関わらずカメラの速度が一定に保たれ、同じような体験が得られます。
    533 </p>
    534 
    535 <p>
    536   To calculate the <var>deltaTime</var> value we keep track of 2 global variables:
    537   <var>deltaTime</var>の値を計算する為に2つの大域変数を追跡します:
    538 </p>
    539 
    540 <pre><code>
    541 float deltaTime = 0.0f;	// Time between current frame and last frame
    542 float deltaTime = 0.0f;	// 直前のフレームと現在のフレームの間の時間
    543 float lastFrame = 0.0f; // Time of last frame
    544 float lastFrame = 0.0f; // 直前のフレームの時刻
    545 </code></pre>
    546 
    547 <p>
    548   Within each frame we then calculate the new <var>deltaTime</var> value for later use:
    549   各フレームにおいて<var>deltaTime</var>を計算して後の利用に備えます:
    550 </p>
    551 
    552 <pre><code>
    553 float currentFrame = <function id='47'>glfwGetTime</function>();
    554 deltaTime = currentFrame - lastFrame;
    555 lastFrame = currentFrame;  
    556 </code></pre>
    557 
    558 <p>
    559   Now that we have <var>deltaTime</var> we can take it into account when calculating the velocities:
    560   <var>deltaTime</var>が得られたので速度の計算に組込みます:
    561 </p>
    562 
    563 <pre><code>
    564 void processInput(GLFWwindow *window)
    565 {
    566     float cameraSpeed = 2.5f * deltaTime;
    567     [...]
    568 }
    569 </code></pre>
    570 
    571 <p>
    572   Since we're using <var>deltaTime</var> the camera will now move at a constant speed of <code>2.5</code> units per second. Together with the previous section we should now have a much smoother and more consistent camera system for moving around the scene:
    573   <var>deltaTime</var>を使っているのでカメラは秒速<code>2.5</code>というような一定の速度では動きません。前節で作成したものと合わせると、よりなめらかで一定の動きでカメラを移動できるようになります:
    574 </p>
    575 
    576 <div class="video paused" onclick="ClickVideo(this)">
    577   <video width="600" height="450" loop>
    578     <source src="/video/getting-started/camera_smooth.mp4" type="video/mp4" />
    579     <img src="/img/getting-started/camera_smooth.png" class="clean"/>    
    580   </video>
    581 </div>
    582 
    583 <p>
    584   And now we have a camera that walks and looks equally fast on any system. Again, check the  <a href="/code_viewer_gh.php?code=src/1.getting_started/7.2.camera_keyboard_dt/camera_keyboard_dt.cpp" target="_blank">source code</a> if you're stuck. We'll see the <var>deltaTime</var> value frequently return with anything movement related.
    585   これにてどんなシステム上でも同じように動き回れるカメラの実装が完了しました。どこかで詰まったら<a href="/code_viewer_gh.php?code=src/1.getting_started/7.2.camera_keyboard_dt/camera_keyboard_dt.cpp" target="_blank">ソースコード</a>を確認して下さい。以降においてもなんらかの動きを作成する場合、<var>deltaTime</var>をしばしば利用することになります。
    586 </p>
    587 
    588 <h1>Look around</h1>
    589 <h1>視点の移動</h1>
    590 <p>
    591   Only using the keyboard keys to move around isn't that interesting. Especially since we can't turn around making the movement rather restricted. That's where the mouse comes in!
    592   キーボードの入力により動き回るだけではそんなに面白くありません。カメラの向きを変更できない為に動きが制限されているからです。そこでマウスの登場です。
    593 </p>
    594 
    595 <p>
    596   To look around the scene we have to change the <var>cameraFront</var> vector based on the input of the mouse. However, changing the direction vector based on mouse rotations is a little complicated and requires some trigonometry. If you do not understand the trigonometry, don't worry, you can just skip to the code sections and paste them in your code; you can always come back later if you want to know more.
    597   あちこち見て回るにはマウスからの入力に応じて<var>cameraFront</var>を変更する必要があります。しかしマウスの回転に応じて方向ベクトルを変化させるのは少し煩雑で、三角関数が必要です。三角関数を知らない人も心配は不要です。コードの章まで読み飛してコピペして下さい。内容を知りたくなった時に戻って来れば結構です。
    598 </p>
    599 
    600 <h2>Euler angles</h2>
    601 <h2>オイラー角</h2>
    602 <p>
    603   Euler angles are 3 values that can represent any rotation in 3D, defined by Leonhard Euler somewhere in the 1700s. There are 3 Euler angles: <em>pitch</em>, <em>yaw</em> and <em>roll</em>. The following image gives them a visual meaning:
    604   オイラー角は3次元空間における任意の角度を表わすことができる3つの値です。1700年代にレオンハルト・オイラーによって定義されました。オイラー角を構成する3つの角はそれぞれ<em>仰角</em>、<em>方位角</em>、<em>傾斜角</em>です。これらの角を図示すると以下のようになります:
    605 </p>
    606 
    607 <img src="/img/getting-started/camera_pitch_yaw_roll.png" alt="Euler angles yaw pitch and roll" class="clean"/>
    608 
    609 <p>
    610   The <def>pitch</def> is the angle that depicts how much we're looking up or down as seen in the first image. The second image shows the <def>yaw</def> value which represents the magnitude we're looking to the left or to the right. The <def>roll</def> represents how much we <em>roll</em> as mostly used in space-flight cameras. Each of the Euler angles are represented by a single value and with the combination of all 3 of them we can calculate any rotation vector in 3D.
    611   <def>仰角(pitch)</def>は1つ目の図の通り、どのくらい見上げているか、あるいは見下げているかを表わします。<def>方位角</def>は2つ目の図の通り、左右の角度です。<def>傾斜角</def>はどのくらい<em>傾いている</em>かを表わし、特に空間中を飛んでいるカメラのようなものに利用されます。これら3つの角の組み合わせにより3次元空間上の任意の回転を表わせます。
    612 </p>
    613 
    614 <p>
    615   For our camera system we only care about the yaw and pitch values so we won't discuss the roll value here. Given a pitch and a yaw value we can convert them into a 3D vector that represents a new direction vector. The process of converting yaw and pitch values to a direction vector requires a bit of trigonometry. and we start with a basic case:
    616   これから作成するカメラにおいては仰角と方位角のみを考えますので、傾斜角については議論しません。仰角と方位角が与えられると、その方向を向いた3次元のベクトルを作成できます。仰角と方位角の値を方向ベクトルに変換するために、三角関数の知識が必要です。まずは基本的な場合から始めましょう:
    617 </p>
    618   
    619 <p>
    620   Let's start with a bit of a refresher and check the general right triangle case (with one side at a 90 degree angle):
    621   復習の意味も兼ねて、一般的な直角三角形を用いて説明します:
    622 
    623 <img src="/img/getting-started/camera_triangle.png" class="clean"/>
    624 
    625 <p>
    626   If we define the hypotenuse to be of length <code>1</code> we know from trigonometry (soh cah toa) that the adjacant side's length is \(\cos \ {\color{red}x}/{\color{purple}h} = \cos \ {\color{red}x}/{\color{purple}1} = \cos\ {\color{red}x}\) and that the opposing side's length is \(\sin \ {\color{green}y}/{\color{purple}h} = \sin \ {\color{green}y}/{\color{purple}1} = \sin\ {\color{green}y.}\)  This gives us some general formulas for retrieving the length in both the <code>x</code> and <code>y</code> sides on right triangles, depending on the given angle. Let's use this to calculate the components of the direction vector.
    627   斜辺の長さを<code>1</code>とした場合、三角関数を使うと、底辺の長さは\(\cos \ {\color{red}x}/{\color{purple}h} = \cos \ {\color{red}x}/{\color{purple}1} = \cos \ {\color{red}x}\)、高さは\(\sin \ {\color{green}y}/{\color{purple}h} = \sin \ {\color{green}y}/{\color{purple}1} = \sin \ {\color{green}y}\)となります。
    628 </p>
    629   
    630 <p>
    631   Let's imagine this same triangle, but now looking at it from a top perspective with the adjacent and opposite sides being parallel to the scene's x and z axis (as if looking down the y-axis). 
    632   これと同じ三角形を空間上で考えましょう。座標空間を上から見下ろし、三角形の底辺と対辺をそれぞれ空間のx軸とz軸に平行になるように置きます。
    633 </p>
    634   
    635 <img src="/img/getting-started/camera_yaw.png" class="clean"/>
    636 
    637 <p>
    638   If we visualize the yaw angle to be the counter-clockwise angle starting from the <code>x</code> side we can see that the length of the <code>x</code> side relates to <code>cos(yaw)</code>. And similarly how the length of the <code>z</code> side relates to <code>sin(yaw)</code>. 
    639   方位角を<code>x</code>軸から反時計回りの角度として定義すると、<code>x</code>軸の辺の長さは<code>cos(yaw)</code>となり、同様に<code>z</code>軸の辺は<code>sin(yaw)</code>となります。
    640 </p>  
    641   
    642 <p>
    643   If we take this knowledge and a given <code>yaw</code> value we can use it to create a camera direction vector:
    644   このことを用いると、<code>yaw</code>の値から以下のようにカメラの方向ベクトルを作成できます:
    645 </p>
    646   
    647 <pre><code>
    648 glm::vec3 direction;
    649 direction.x = cos(<function id='63'>glm::radians</function>(yaw)); // Note that we convert the angle to radians first
    650 direction.x = cos(<function id='63'>glm::radians</function>(yaw)); // 角度の値をラジアンに変換していることに注意
    651 direction.z = sin(<function id='63'>glm::radians</function>(yaw));
    652 </code></pre>
    653   
    654 <p>
    655   This solves how we can get a 3D direction vector from a yaw value, but pitch needs to be included as well. Let's now look at the <code>y</code> axis side as if we're sitting on the <code>xz</code> plane: 
    656   これで方位角から3次元の方向ベクトルを得られますが、これに加えて仰角も考慮する必要があります。今度は<code>xz</code>平面から<code>y</code>軸を眺めてみましょう:
    657 </p>
    658   
    659 
    660 <img src="/img/getting-started/camera_pitch.png" class="clean"/>
    661 
    662 <p>
    663   Similarly, from this triangle we can see that the direction's y component equals <code>sin(pitch)</code> so let's fill that in:
    664   同様にしてこの三角形から、方向ベクトルのy要素は<code>sin(pitch)</code>となります:
    665 </p>
    666   
    667   
    668 <pre><code>
    669 direction.y = sin(<function id='63'>glm::radians</function>(pitch));  
    670 </code></pre>
    671     
    672 <p>
    673   However, from the pitch triangle we can also see the <code>xz</code> sides are influenced by <code>cos(pitch)</code> so we need to make sure this is also part of the direction vector. With this included we get the final direction vector as translated from yaw and pitch Euler angles:
    674   加えてこの仰角を表わす三角形から<code>xz</code>平面の成分は<code>cos(pitch)</code>となるので、これを方向ベクトルに組込む必要があります。以上を踏まえると方向ベクトルは以下のようになります:
    675 </p>
    676   
    677 <pre><code>
    678 direction.x = cos(<function id='63'>glm::radians</function>(yaw)) * cos(<function id='63'>glm::radians</function>(pitch));
    679 direction.y = sin(<function id='63'>glm::radians</function>(pitch));
    680 direction.z = sin(<function id='63'>glm::radians</function>(yaw)) * cos(<function id='63'>glm::radians</function>(pitch));
    681 </code></pre>
    682   
    683 <p>
    684   This gives us a formula to convert yaw and pitch values to a 3-dimensional direction vector that we can use for looking around. 
    685   これが仰角と方位角を、3次元の方向ベクトルに変換する公式です。このベクトルをカメラの視線として利用できます。
    686 </p>
    687   
    688 <p>
    689   We've set up the scene world so everything's positioned in the direction of the negative z-axis. However, if we look at the <code>x</code> and <code>z</code> yaw triangle we see that a \(\theta\) of <code>0</code> results in the camera's <code>direction</code> vector to point towards the positive x-axis. To make sure the camera points towards the negative z-axis by default we can give the <code>yaw</code> a default value of a 90 degree clockwise rotation. Positive degrees rotate counter-clockwise so we set the default <code>yaw</code> value to:
    690   以前設定した空間において、全ての物体はz軸が負の位置に置かれていました。しかし<code>xz</code>平面における方位角を表わす三角形を見ると、\(\theta\)が<code>0</code>である場合カメラの<code>direction</code>ベクトルがx軸正の方向を向くことが分かります。初期段階においてカメラがz軸負の方向を見るようにするために、<code>yaw</code>の初期値を時計回りに90度回転させるべきです。正の値は反時計回りの回転を表わすので、<code>yaw</code>の初期値は以下のように設定します:
    691 </p>
    692   
    693 <pre><code>
    694 yaw = -90.0f;
    695 </code></pre>
    696   
    697 <p>
    698     You've probably wondered by now: how do we set and modify these yaw and pitch values?
    699 	それではどのようにしてこの仰角と方位角を更新すればよいでしょうか。
    700 </p>
    701 
    702 
    703 <h2>Mouse input</h2>
    704 <h2>マウスからの入力</h2>
    705 <p>
    706   The yaw and pitch values are obtained from mouse (or controller/joystick) movement where horizontal mouse-movement affects the yaw and vertical mouse-movement affects the pitch. The idea is to store the last frame's mouse positions and calculate in the current frame how much the mouse values changed. The higher the horizontal or vertical difference, the more we update the pitch or yaw value and thus the more the camera should move. 
    707   方位角と仰角の値はマウス(あるいはコントローラ、ジョイスティック等)の動きから得ます。マウスの水平方向の移動により方位角を、垂直方向の移動により仰角を変更するようにします。直前のフレームにおけるマウスの位置を保存しておいて、現在のフレームにおけるマウスの位置との差を計算します。水平方向や垂直方向の動きが大きいほど、方位角や仰角の変化量も大きくなるようにし、カメラも大きく動かされるようにしましょう。
    708 </p>
    709 
    710 <p>
    711   First we will tell GLFW that it should hide the cursor and <def>capture</def> it. Capturing a cursor means that, once the application has focus, the mouse cursor stays within the center of the window (unless the application loses focus or quits). We can do this with one simple configuration call:
    712   まずはGLFWがカーソルを<def>キャプチャ</def>し非表示にするようにします。カーソルのキャプチャとはアプリケーションにフォーカスしたらマウスのカーソルを(別のアプリケーションにフォーカスが移るか、このアプリケーションが終了するまで)ウィンドウの中央に固定しておくことを言います。これは1つの簡単な設定により実行できます:
    713 </p>
    714 
    715 <pre><code>
    716 glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);  
    717 </code></pre>
    718 
    719 <p>
    720   After this call, wherever we move the mouse it won't be visible and it should not leave the window. This is perfect for an FPS camera system.
    721   この関数を実行することで、マウスを動かしても表示されず、ウィンドウの外に出ることもなくなります。FPSのカメラには最適です。
    722 </p>
    723 
    724 <p>
    725 To calculate the pitch and yaw values we need to tell GLFW to listen to mouse-movement events. We do this by creating a callback function with the following prototype:
    726 仰角と方位角を計算する為、GLFWにマウスのイベントを監視させる必要があります。その為に以下のようなプロトタイプのコールバック関数を定義します:
    727 </p>
    728 
    729 <pre><code>
    730 void mouse_callback(GLFWwindow* window, double xpos, double ypos);
    731 </code></pre>
    732 
    733 <p>
    734   Here <var>xpos</var> and <var>ypos</var> represent the current mouse positions. As soon as we register the callback function with GLFW each time the mouse moves, the <fun>mouse_callback</fun> function is called:
    735   ここで、<var>xpos</var>と<var>ypos</var>は現在のマウスの位置を表わします。この関数をGLFWにコールバックとして登録すれば、マウスが動く度に<fun>mouse_callback</fun>が呼ばれます:
    736 </p>
    737 
    738 <pre><code>
    739 glfwSetCursorPosCallback(window, mouse_callback);  
    740 </code></pre>
    741 
    742 <p>
    743   When handling mouse input for a fly style camera there are several steps we have to take  before we're able to fully calculate the camera's direction vector:
    744   マウスの入力により飛行型のカメラを操作する場合、実際にカメラの方向ベクトルを計算する上で以下の手順を踏まなければいけません:
    745   
    746   <ol>
    747     <li>Calculate the mouse's offset since the last frame.</li>
    748 	<li>直前のフレームからのマウスの移動量を計算。</li>
    749     <li>Add the offset values to the camera's yaw and pitch values.</li>
    750 	<li>その移動量をカメラの方位角と仰角に加算。</li>
    751     <li>Add some constraints to the minimum/maximum pitch values.</li>
    752 	<li>仰角をある範囲に制限。</li>
    753     <li>Calculate the direction vector.</li>
    754 	<li>方向ベクトルを計算。</li>
    755   </ol>
    756 </p>
    757 
    758 <p>
    759   The first step is to calculate the offset of the mouse since last frame. We first have to store the last mouse positions in the application, which we initialize to be in the center of the screen (screen size is <code>800</code> by <code>600</code>) initially:
    760   最初の作業は直近のフレームからのマウスの移動量を計算することです。まず直前のマウスの位置をアプリケーションに保存します。この変数の初期値は画面の中心にしておきます(画面の大きさは<code>800x600</code>です)。
    761 </p>
    762 
    763 <pre class="cpp"><code>
    764 float lastX = 400, lastY = 300;
    765 </code></pre>
    766 
    767 <p>
    768   Then in the mouse's callback function we calculate the offset movement between the last and current frame:
    769   次にマウスのコールバック関数内で直前のフレームからの移動量を計算します:
    770 </p>
    771 
    772 <pre><code>
    773 float xoffset = xpos - lastX;
    774 float yoffset = lastY - ypos; // reversed since y-coordinates range from bottom to top
    775 float yoffset = lastY - ypos; // y座標は下から上へ増加するのでx座標とは逆
    776 lastX = xpos;
    777 lastY = ypos;
    778 
    779 const float sensitivity = 0.1f;
    780 xoffset *= sensitivity;
    781 yoffset *= sensitivity;
    782 </code></pre>
    783 
    784 <p>
    785   Note that we multiply the offset values by a <var>sensitivity</var> value. If we omit this multiplication the mouse movement would be way too strong; fiddle around with the sensitivity value to your liking.
    786 	<var>sensitivity</var>(感度)を移動量の値に掛けていることに注意して下さい。これをしないとマウスによる動きが速すぎるかと思います。感度を変化させて好みの値を探って下さい。
    787 </p>
    788 
    789 <p>
    790   Next we add the offset values to the globally declared <var>pitch</var> and <var>yaw</var> values:
    791   続いて大域的に宣言されている<var>pitch</var>と<var>yaw</var>に加算します:
    792 </p>
    793 
    794 <pre><code>
    795 yaw   += xoffset;
    796 pitch += yoffset;  
    797 </code></pre>
    798 
    799 <p>
    800   In the third step we'd like to add some constraints to the camera so users won't be able to make weird camera movements (also causes a LookAt flip once direction vector is parallel to the world up direction). The pitch needs to be constrained in such a way that users won't be able to look higher than <code>89</code> degrees (at <code>90</code> degrees we get the LookAt flip) and also not below <code>-89</code> degrees. This ensures the user will be able to look up to the sky or below to his feet but not further. The constraints work by replacing the Euler value with its constraint value whenever it breaches the constraint:
    801   3つ目の作業はカメラの動く範囲に制限を加え、ユーザーがおかしなカメラの動きをできないようにすることです。カメラの方向ベクトルが大域空間の上向きのベクトルと平行になった時に視線がひっくり返るのです。すなわち仰角が<code>90</code>度になると視線の反転が起こるので、この角を<code>89</code>度以下、そして<code>-89</code>度以上に制限します。こうすることでユーザーは空を見上げたり足元を見下げたりはできますがそれ以上はできなくなります。このような制限は、この角が制限を越えたときに制限の最大値あるいは最小値に置き換えることで実現できます:
    802 </p>
    803 
    804 <pre><code>
    805 if(pitch &gt; 89.0f)
    806   pitch =  89.0f;
    807 if(pitch &lt; -89.0f)
    808   pitch = -89.0f;
    809 </code></pre>
    810 
    811 <p>
    812   Note that we set no constraint on the yaw value since we don't want to constrain the user in horizontal rotation. However, it's just as easy to add a constraint to the yaw as well if you feel like it.
    813   ここでは水平方向のカメラの動きに制限を設けたくないので、方位角の値には制限をかけません。しかし必要であれば仰角と同様の方法で制限することができます。
    814 </p>
    815 
    816 <p>
    817   The fourth and last step is to calculate the actual direction vector using the formula from the previous section:
    818   最後の作業は方向ベクトルを前章の公式から計算することです:
    819 </p>
    820 
    821 <pre><code>
    822 glm::vec3 direction;
    823 direction.x = cos(<function id='63'>glm::radians</function>(yaw)) * cos(<function id='63'>glm::radians</function>(pitch));
    824 direction.y = sin(<function id='63'>glm::radians</function>(pitch));
    825 direction.z = sin(<function id='63'>glm::radians</function>(yaw)) * cos(<function id='63'>glm::radians</function>(pitch));
    826 cameraFront = glm::normalize(direction);
    827 </code></pre>
    828   
    829   <p>
    830     This computed direction vector then contains all the rotations calculated from the mouse's movement. Since the <var>cameraFront</var> vector is already included in glm's <fun>lookAt</fun> function we're set to go.
    831 	この計算によりマウスの動きを加味した方向ベクトルが得られます。<var>cameraFront</var>ベクトルは既にglmの<fun>lookAt</fun>関数に含まれているので、これで準備完了です。
    832 </p>
    833 
    834 <p>
    835   If you'd now run the code you'll notice the camera makes a large sudden jump whenever the window first receives focus of your mouse cursor. The cause for this sudden jump is that as soon as your cursor enters the window the mouse callback function is called with an <var>xpos</var> and <var>ypos</var> position equal to the location your mouse entered the screen from. This is often a position that is significantly far away from the center of the screen, resulting in large offsets and thus a large movement jump. We can circumvent this issue by defining a global <code>bool</code> variable to check if this is the first time we receive mouse input. If it is the first time, we update the initial mouse positions to the new <var>xpos</var> and <code>ypos</code> values. The resulting mouse movements will then use the newly entered mouse's position coordinates to calculate the offsets:
    836   現段階でのコードを実行すると最初にウィンドウにマウスのカーソルでフォーカスした際にカメラの視点が大きく移動することに気付くでしょう。マウスのカーソルがウィンドウに入った時にマウスのコールバック関数が呼ばれますがこの時引数として渡される<var>xpos</var>と<var>ypos</var>がその時のカーソルの位置であり、ウィンドウの中心からは大きく離れているため、中心から大きく移動したものと見做され、結果としてカメラの大きな移動になります。この問題に対処する為に、マウスからの入力を受けとるのが初めてかどうかを保存した大域的な真偽値の変数を定義します。マウスからの最初の入力があった場合、マウスの初期位置を引数として渡された<var>xpos</var>と<var>ypos</var>に変更します。そうするとマウスの移動量の計算に新しく入力されたマウスの位置が利用されるようになります:
    837 </p>
    838 
    839 <pre><code>
    840 if (firstMouse) // initially set to true
    841 {
    842     lastX = xpos;
    843     lastY = ypos;
    844     firstMouse = false;
    845 }
    846 </code></pre>
    847 
    848 <p>
    849   The final code then becomes:
    850 </p>
    851 
    852 <pre><code>
    853 void mouse_callback(GLFWwindow* window, double xpos, double ypos)
    854 {
    855     if (firstMouse)
    856     {
    857         lastX = xpos;
    858         lastY = ypos;
    859         firstMouse = false;
    860     }
    861   
    862     float xoffset = xpos - lastX;
    863     float yoffset = lastY - ypos; 
    864     lastX = xpos;
    865     lastY = ypos;
    866 
    867     float sensitivity = 0.1f;
    868     xoffset *= sensitivity;
    869     yoffset *= sensitivity;
    870 
    871     yaw   += xoffset;
    872     pitch += yoffset;
    873 
    874     if(pitch &gt; 89.0f)
    875         pitch = 89.0f;
    876     if(pitch &lt; -89.0f)
    877         pitch = -89.0f;
    878 
    879     glm::vec3 direction;
    880     direction.x = cos(<function id='63'>glm::radians</function>(yaw)) * cos(<function id='63'>glm::radians</function>(pitch));
    881     direction.y = sin(<function id='63'>glm::radians</function>(pitch));
    882     direction.z = sin(<function id='63'>glm::radians</function>(yaw)) * cos(<function id='63'>glm::radians</function>(pitch));
    883     cameraFront = glm::normalize(direction);
    884 }  
    885 </code></pre>
    886 
    887 <p>
    888   There we go! Give it a spin and you'll see that we can now freely move through our 3D scene! 
    889 これで完成です。コードを実行して3次元空間を自由に動き回れるか確認してみましょう。
    890 </p>
    891 
    892 
    893 <h2>Zoom</h2>
    894 <h2>拡大</h2>
    895 <p>
    896   As a little extra to the camera system we'll also implement a zooming interface. In the previous chapter we said the <em>Field of view</em> or <em>fov</em> largely defines how much we can see of the scene. When the field of view becomes smaller, the scene's projected space gets smaller. This smaller space is projected over the same NDC, giving the illusion of zooming in. To zoom in, we're going to use the mouse's scroll wheel. Similar to mouse movement and keyboard input we have a callback function for mouse scrolling:
    897   最後におまけとしてカメラに拡大機能を実装してみましょう。前章において、<em>視野角(fov)</em>が画面上で見える範囲を主に規定することをお話ししました。視野角が小さくなると空間の中で射影される範囲が小さくなります。範囲が狭くなった空間もそれまでと同じ大きさのNDCに投影されるので、結果として拡大したように見えます。ここでは拡大の操作をするためにマウスのホイールを利用しましょう。マウスの動きやキーボードの入力の時と同様に、マウスのスクロールに対してもコールバック関数を定義します。
    898 </p>
    899 
    900 <pre><code>
    901 void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
    902 {
    903     fov -= (float)yoffset;
    904     if (fov &lt 1.0f)
    905         fov = 1.0f;
    906     if (fov &gt; 45.0f)
    907         fov = 45.0f; 
    908 }
    909 </code></pre>
    910 
    911 <p>
    912   When scrolling, the <var>yoffset</var> value tells us the amount we scrolled vertically. When the <fun>scroll_callback</fun> function is called we change the content of the globally declared <var>fov</var> variable. Since <code>45.0</code> is the default fov value we want to constrain the zoom level between <code>1.0</code> and <code> 45.0</code>.
    913   スクロールすると<var>yoffset</var>の値がその時のスクロール量を保持します。<fun>scroll_callback</fun>関数が呼ばれた時に、大域的に宣言されている<var>fov</var>の値を変更するようにします。<code>45.0</code>が視野角の既定値ですが、これを<code>1.0</code>から<code>45.0</code>の間で動かせるようにしましょう。
    914 </p>
    915 
    916 <p>
    917   We now have to upload the perspective projection matrix to the GPU each frame, but this time with the <var>fov</var> variable as its field of view:
    918   透視投影行列をフレーム毎に更新する必要がありますが、この時に視野角の値として<var>fov</var>を利用するようにします:
    919 </p>
    920 
    921 <pre><code>
    922 projection = <function id='58'>glm::perspective</function>(<function id='63'>glm::radians</function>(fov), 800.0f / 600.0f, 0.1f, 100.0f);  
    923 </code></pre>
    924 
    925 <p>
    926   And lastly don't forget to register the scroll callback function:
    927   最後にスクロールのコールバック関数を登録するのを忘れないようにしましょう:
    928 </p>
    929 
    930 <pre><code>
    931 <function id='64'>glfwSetScrollCallback</function>(window, scroll_callback); 
    932 </code></pre>
    933 
    934 <p>
    935   And there you have it. We implemented a simple camera system that allows for free movement in a 3D environment.
    936   これで完成です。3次元空間上を自由に動き回れるカメラが実装できました。
    937 </p>
    938 
    939 <div class="video paused" onclick="ClickVideo(this)">
    940   <video width="600" height="450" loop>
    941     <source src="/video/getting-started/camera_mouse.mp4" type="video/mp4" />
    942     <img src="/img/getting-started/camera_mouse.png" class="clean"/>    
    943   </video>
    944 </div>
    945 
    946 <p>
    947   Feel free to experiment a little and if you're stuck compare your code with the  <a href="/code_viewer_gh.php?code=src/1.getting_started/7.3.camera_mouse_zoom/camera_mouse_zoom.cpp" target="_blank">source code</a>.
    948   いろいろ変更して好きに実験してみて下さい。どこかで分からなくなったらご自分のコードとこの<a href="/code_viewer_gh.php?code=src/1.getting_started/7.3.camera_mouse_zoom/camera_mouse_zoom.cpp" target="_blank">ソースコード</a>を比較して下さい。
    949 </p>
    950 
    951 <h1>Camera class</h1>
    952 <h1>カメラのクラス</h1>
    953 <p>
    954   In the upcoming chapters we'll always use a camera to easily look around the scenes and see the results from all angles. However, since the camera code can take up a significant amount of space on each chapter we'll abstract its details a little and create our own camera object that does most of the work for us with some neat little extras. Unlike the Shader chapter we won't walk you through creating the camera class, but provide you with the (fully commented) source code if you want to know the inner workings. 
    955   以降の章では作成したものを様々な角度から確認するためにカメラを利用します。しかしカメラのコードは場所をとるので細かい部分を少し抽象化するためにカメラオブジェクトを作成し、コードをすっきりさせるようにします。シェーダーの章においては細かく解説しましたが今回は(コメントをたくさん付けた)ソースコードをご自身で見て内容を確認していただくことにします。
    956 </p>
    957 
    958 <p>
    959   Like the <code>Shader</code> object, we define the camera class entirely in a single header file. You can find the camera class <a href="/code_viewer_gh.php?code=includes/learnopengl/camera.h" target="_blank">here</a>; you should be able to understand the code after this chapter. It is advised to at least check the class out once as an example on how you could create your own camera system.
    960   <code>Shader</code>オブジェクトと同様、カメラのクラスはひとつのヘッダファイルに記述します。<a href="/code_viewer_gh.php?code=includes/learnopengl/camera.h" target="_blank">ここ</a>でカメラクラスを確認して下さい。ここまで読み終えた方には十分理解できるはずです。一度はこのクラスの中身にさっと目を通してカメラのシステムの作成方法を確認して下さい。
    961 </p>
    962 
    963 <warning>
    964   The camera system we introduced is a fly like camera that suits most purposes and works well with Euler angles, but be careful when creating different camera systems like an FPS camera, or a flight simulation camera. Each camera system has its own tricks and quirks so be sure to read up on them. For example, this fly camera doesn't allow for pitch values higher than or equal to <code>90</code> degrees and a static up vector of <code>(0,1,0)</code> doesn't work when we take roll values into account. 
    965   ここで作成したカメラは飛んでいるようなカメラで、オイラー角と共にほとんどの目的に利用できます。しかしFPSのカメラやフライトシミュレーションのカメラのような別のカメラを作成する場合は注意が必要です。角カメラにはそれぞれ独特の手法が必要なので、利用する場合はそのカメラについての解説を読むようにして下さい。例えばここで作ったカメラは仰角を<code>90</code>度以上にできませんし、また傾斜角を考慮したい場合はカメラの上方向のベクトルを<code>(0, 1, 0)</code>に保っているのは間違いです。
    966 </warning>
    967 
    968 <p>
    969   The updated version of the source code using the new camera object can be found  <a href="/code_viewer_gh.php?code=src/1.getting_started/7.4.camera_class/camera_class.cpp" target="_blank">here</a>.
    970   カメラオブジェクトを利用したコードは<a href="/code_viewer_gh.php?code=src/1.getting_started/7.4.camera_class/camera_class.cpp" target="_blank">こちら</a>です。
    971 </p>
    972 
    973 <h2>Exercises</h2>
    974 <h2>演習</h2>
    975 <p>
    976   <ul>
    977     <li>See if you can transform the camera class in such a way that it becomes a <strong>true</strong> fps camera where you cannot fly; you can only look around while staying on the <code>xz</code> plane: <a href="/code_viewer_gh.php?code=src/1.getting_started/7.5.camera_exercise1/camera_exercise1.cpp" target="_blank">solution</a>.</li>
    978 	<li>カメラクラスを変更して<strong>本当の</strong>FPSのカメラを実装して下さい。すなわち周囲を見回せても<code>xz</code>平面を離れられないようにして下さい: <a href="/code_viewer_gh.php?code=src/1.getting_started/7.5.camera_exercise1/camera_exercise1.cpp" target="_blank">解答</a>。</li>
    979     <li>Try to create your own LookAt function where you manually create a view matrix as discussed at the start of this chapter. Replace glm's LookAt function with your own implementation and see if it still acts the same: <a href="/code_viewer_gh.php?code=src/1.getting_started/7.6.camera_exercise2/camera_exercise2.cpp" target="_blank">solution</a>.</li>
    980 	<li>この章の初めに紹介した視野行列を自身で作成し、それを利用してLookAt関数を実装して下さい。glmのLookAt関数を自身で作成したものに置き換え、同じように機能するか確認して下さい: <a href="/code_viewer_gh.php?code=src/1.getting_started/7.6.camera_exercise2/camera_exercise2.cpp" target="_blank">解答</a>。</li>
    981   </ul>
    982 </p>
    983     </div>
    984 </body>
    985 </html>
    986 	</main>
    987 </body>
    988 </html>