1 :
へなちょこCプログラマ :
アルゴリズムが全くわかりません。
A4が出たときに、自分もこんなの作ろうと
いろいろ考えたのですが。
2 :
名無しさん@お腹いっぱい。 :2000/09/07(木) 00:06
ああ、これマジで知りたいなあ。
とりあえずフツーの2Dと違うのは座標情報に「高さ」の
情報が付加されるってことだよね。
識者の書き込みをきぼーん。
3 :
2 :2000/09/07(木) 00:12
ただいまアルゴリズム検索中。
・描画は奥から手前に行うべし
こうすることによって、手前に高い木とかがあると、
その奥にいるキャラおよびマップが隠れてされる、と。
4 :
名無しさん@お腹いっぱい。 :2000/09/07(木) 00:14
[誤]隠れてされる
[正]隠れて描画される
5 :
名無しさん@お腹いっぱい。 :2000/09/07(木) 00:24
てゆうか、なにがわかんないの?
めちゃくちゃ簡単だと思うのだが。
わからないの部分を言ってみな。
6 :
2 :2000/09/07(木) 00:45
タクティクスみたいな静的な描画処理は簡単だと思うんですけど、
ランドストーカーみたいなアクション要素が入ったアルゴリズムに
興味があります。例えば階段を上るという処理を考えた場合、
どうすればいいのか混乱しちゃいます。
そこで質問。
「クォータービューにおけるジャンプ処理はどうやりますか?」
ちょっと1を見て触発された好奇心がてらの質問なんで、
テキトーなお返事でもかまいません。
つきあっていただければこれ幸いです。
7 :
2 :2000/09/07(木) 00:55
んで、検索しても見つからないので一人で考えてみる(暇だねおれも)。
まず、Model-View-Controller(MVC)的なアプローチで考えてみる。
即ち、ビューとモデル(情報)を切り離す、と。
モデルにおいては、2次元配列的な座標オブジェクトを用意する。
座標オブジェクトは x@` y@` height@` view 情報を持つとする。
[ ジャンプルーチン ]
高さの判定は相対的な情報を用いる。
1 | 1 | 2
――――――――
0 |自分 | 0
――――――――
0 | 0 | 0
この3×3の二次元配列は(自分のいる高さより)上が 1 高くて
右上が 2 高い。1高いならばジャンプできて、それよりも大きければ
ジャンプできないとする。
8 :
2@ちょっと飽きてきた :2000/09/07(木) 01:24
[ コントローラーについて ]
ビュー上のキーとモデル上のキーの関係
ビュー …… モデル
右上 …… 右
左上 …… 上
左下 …… 左
右下 …… 下
以上のキーマップより、座標は次のような感じ。
B
/\
/\/\
/\/\/\
/\/\/\/\D
A\/\/\/\/
\/\/\/
\/\/
\/
C
A(1@` 1) − B(1@` 4)
| |
C(4@` 1) − C(4@` 4)
9 :
名無しさん@お腹いっぱい。 :2000/09/07(木) 04:08
つづきは?(ワクワク
10 :
名無しさん@お腹いっぱい。 :2000/09/07(木) 05:05
ランドストーカーなら、普通に3次元配列の
ブロックマップ作ってやりゃいいんじゃないですか?
あとはスーマリとかでやってる処理をZ軸にも拡張するだけ。
レンダリングは、ファイナルファンタジータクティクスなんかは
3Dで平行投影してますな。2Dで描くより今時はこちらが旬かと。
11 :
10 :2000/09/07(木) 05:08
あ、3Dでってのは、もちろんポリゴンでってことね。
12 :
名無しさん@お腹いっぱい。 :2000/09/07(木) 10:45
そんなんでMVCって言うなよ ^^;;)>2
13 :
2 :2000/09/07(木) 16:28
というわけで、上の仕様をもとに
描画テストコードをJavaで書いてみました。
「ブロック座標から実座標への変換」と
「描画ループ x 座標は右から左へ y 座標は上から下へ」がミソです。
全角→半角×2変換を忘れずに。
>>12 >そんなんでMVCって言うなよ ^^;;)
確かに(笑)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class QViewDrawBase
{
public static int BLOCK_SIZE = 16;
public static int HEIGHT_SIZE = 20;
public static int SCR_OFFSET = 200;
public void draw(Graphics g@` int argX@` int argY@` int height@` int view)
{
int b = BLOCK_SIZE;
// ブロック座標から実座標への変換 ////////////////////////////
int x = argX * b;
int y = x;
for(int i=0; i<argY; i++){
x += b;
y -= b;
}
//////////////////////////////////////////////////////////////
x += SCR_OFFSET;
y += SCR_OFFSET;
int[] xPoints = new int[] { x@` x+b@` x+b*2@` x+b };
int[] yPoints = new int[] { y@` y+b@` y@` y-b };
g.setColor(Color.black);
g.drawPolygon(xPoints@` yPoints@` xPoints.length);
if(height > 0){
int h = height * HEIGHT_SIZE;
// 面1
int[] xhPoints1 = new int[] { x@` x@` x+b@` x+b };
int[] yhPoints1 = new int[] { y@` y-h@` y-h+b@` y+b };
g.setColor(Color.white);
g.fillPolygon(xhPoints1@` yhPoints1@` xhPoints1.length);
g.setColor(Color.black);
g.drawPolygon(xhPoints1@` yhPoints1@` xhPoints1.length);
// 面2
int[] xhPoints2 = new int[] { x+b@` x+b@` x+b*2@` x+b*2 };
int[] yhPoints2 = new int[] { y+b@` y+b-h@` y-h@` y };
g.setColor(Color.white);
g.fillPolygon(xhPoints2@` yhPoints2@` xhPoints2.length);
g.setColor(Color.black);
g.drawPolygon(xhPoints2@` yhPoints2@` xhPoints2.length);
// 面3
int[] xhPoints3 = new int[] { x@` x+b@` x+b*2@` x+b };
int[] yhPoints3 = new int[] { y-h@` y+b-h@` y-h@` y-b-h };
g.setColor(Color.white);
g.fillPolygon(xhPoints3@` yhPoints3@` xhPoints3.length);
g.setColor(Color.black);
g.drawPolygon(xhPoints3@` yhPoints3@` xhPoints3.length);
}
}
}
14 :
2 :2000/09/07(木) 16:29
class QViewPanel extends JPanel
{
private QViewDrawBase qv;
public QViewPanel()
{
qv = new QViewDrawBase();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
setBackground(Color.white);
// 描画ループ x 座標は右から左へ y 座標は上から下へ /////////
for(int i=5; i>=0; i--){
for(int j=0; j<=5; j++){
// テストコードにつき、高さはランダムに
int height = ((int)(Math.random() * 1000)) % 3;
qv.draw(g@` j@` i@` height@` 0);
}
}
//////////////////////////////////////////////////////////////
}
}
class QViewFrame extends JFrame
{
public QViewFrame()
{
setTitle("QViewTest");
setSize(600@` 600);
addWindowListener
(
new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
Container contentPane = getContentPane();
contentPane.add(new QViewPanel());
}
public static void main(String args[])
{
JFrame frame = new QViewFrame();
frame.show();
}
}
15 :
名無しさん@お腹いっぱい。 :2000/09/07(木) 16:48
ちゃんとモデリングして座標変換クラスを作るのがいいと思う
んで画面位置へ投影して描画
16 :
2 :2000/09/07(木) 17:22
あ、x と y が逆になってました。
訂正。
// ブロック座標から実座標への変換 ////////////////////////////
int x = argY * b;
int y = x;
for(int i=0; i<argX; i++){
x += b;
y -= b;
}
System.out.println( x+ " " + y);
ここも訂正。
// 描画ループ x 座標は右から左へ y 座標は上から下へ /////////
for(int i=5; i>=0; i--){
for(int j=0; j<=5; j++){
// テストコードにつき、高さはランダムに
int height = ((int)(Math.random() * 1000)) % 3;
qv.draw(g@` i@` j@` height@` 0);
}
}
多分これであっているはず(自信喪失)。
17 :
2 :2000/09/07(木) 17:37
>>15 >ちゃんとモデリングして座標変換クラスを作るのがいいと思う
>んで画面位置へ投影して描画
えっと、モデリングってことは
>>10 さんのような
ポリゴンによる3D → 2D投影のことですね。なるほど〜。
確かに面白そう。けど、よく知らなかったり(苦笑)。
ただ「ランドストーカー」を昔にプレイして感動したことがあったんです。
内藤寛はいったいどうやってプログラミングしているんだろうって。
そういうこともあって、ローパワーマシンでも動くようなアルゴリズムを
考えてみたいなと思ってこのスレに参加してるので、
もうちょっとこの線で考えてみたいと思います。
ちょっと飽きてきているけど(苦笑)
#ちなみに後学のためにその3D→投影の方法を教えてもらえると、
#幸せだったりします。って図々しいかな?
19 :
名無しさん@お腹いっぱい。 :2000/09/07(木) 21:23
20 :
今更ながら1です :2000/09/07(木) 21:24
私が分からないのは、たとえばビルを描画する場合
単なる矩形なら単に座標を指定して描画するだけですけど
菱形ですよね。その菱形に描画するやり方が分からないんです。
表示はそれとして、「くぐり抜けられる橋」みたいなのの
マップ構造がよくわからない>おれ
ハイトマップ+フラグじゃないだろうし
そういえば、クォータービューというのはどっか(ウルフチーム?)の造語で
英語にないって聞いたけど、ほんと?
クォータービューぐらいでジオメトリ変換なんかしないでね。ケケケ。
各タイル(ユニット?)ごとに透明にしたいところのマスクつくるだけじゃないの〜?
一部のキャラクタを動かす場合は、キャラクタを描画する前にキャラクタを描画した領域だけ、描画前の情報を保存しておくのが定石。
橋なんかをくぐる場合はキャラクタ -> 上になるものの順で描画すればいいだけ。(もちろん裏画面でね)
#最近レベルがますます下がったねえ。
>20
1さんのレベルがわからんので思い切り低レベルな話にします。
(200@`200)-(250@`200)-(250@`250)-(200@`250)-(200@`200)
この順に座標を指定したら矩形が描けますよね?
これら座標を次の式に入れてやります。
Draw_X = (x - y + 100);
Draw_Y = (x + y + 100);
つまり、(100@`500)-(150@`550)-(100@`600)-(50@`550)-(100@`500)
橋は、上の面に橋が書いてあり、それ以外の面が
全部透明の立方体をおいてください。
25 :
>20 :2000/09/08(金) 00:43
まさかビットマップのマスク付き描画がわからないということ?
26 :
こんな感じ? :2000/09/08(金) 02:56
(xx@`yy@`zz) を (xxx@`yyy) に 変換してみる (Y軸に投影)
Xの弧度 = X軸の回転角度 * π /180 ;
Yの弧度 = Y軸の回転角度 * π /180 ;
Zの弧度 = Z軸の回転角度 * π /180
x1 = xx * cos(Yの弧度) + zz * sin(Yの弧度)
z1 = zz * cos(Yの弧度) - xx * sin(Yの弧度)
y1 = yy * cos(xの弧度) - z1 * sin(xの弧度)
xxx = ( x1 * cos(zの弧度) - y1 * sin(zの弧度) )
yyy = ( x1 * sin(zの弧度) + y1 * cos(zの弧度) )
27 :
名無しさん@お腹いっぱい。 :2000/09/08(金) 03:08
>>橋なんかをくぐる場合はキャラクタ -> 上になるものの順で描画すればいいだけ。
2つのリングが絡まっている場合は、この方法ではムリ・・・
陰線処理を教えてやれ、レベルの高いキミ。
ビットマップのマスク付描画も幾何変換も分かってない、かなりの厨房とみた。
クォータービューに限れば、幾何変換は必要ないってば。こいつらバカか?
幾何変換は3D CAD/CAM関連の教科書にはたいてい載ってるから、図書館行くなり、本屋に行って立ち読みするなりしなされ。
手元にある本を一冊だけ紹介。
3次元CGの基礎と応用@` 千葉則茂他@` サイエンス社@` 1997
29 :
>27 :2000/09/08(金) 03:34
最近はメモリを山ほど積んでるんだから、Zバッファ法で十分。
30 :
名無しさん@お腹いっぱい。 :2000/09/08(金) 03:36
>クォータービューぐらいでジオメトリ変換なんかしないでね。ケケケ。
レベルの高いキミ、話の流れ全然読めてへんやろ。
おいらはてっきりクォータービューの高速描画について話しているんだと思ってたよ。
だから、
>>17 ローパワーマシンでも動くようなアルゴリズムを考えてみたい
というのに、ジオメトリ変換を使う方法考えてるなんて、
よっぽど無教養か、頭が壊れてるとしか思えないね。なんて思ったわけだ。ごめんな。
いったい、どんな流れで話しているのか、聞いてみたいものだ。
それにしても、ジオメトリ変換にしたって、
>>26 なんて、ちょっと知恵づいた中3が受験勉強の合間に、鼻くそほじくりながら考えるレベルじゃない?ケケケ。
変換行列がすぐにでてこないのかかなり疑問。π/180なる記述は笑わせてもらったよ。
32 :
>31 :2000/09/08(金) 04:59
やっぱり、話の流れを読めてないね。キミ。
実生活での会話とか下手クソそうだね。
1 と 2 と 3Dを勧めている人の文脈は全く別。
>
>>17 ローパワーマシンでも動くようなアルゴリズムを考えてみたい
>というのに、ジオメトリ変換を使う方法考えてるなんて、
>>17 >#ちなみに後学のため
って2が言ってるじゃん。
33 :
名無しさん@お腹いっぱい。 :2000/09/08(金) 11:16
34 :
名無しさん@お腹いっぱい。 :2000/09/08(金) 11:25
内部のデータ構造からクォータービュー描画のための座標を計算することが
“ジオメトリ変換”
です >> バカ31君
35 :
中3 :2000/09/08(金) 12:05
鼻くそほじくりながら考える中3ですんませんなぁ。
36 :
はずしているかも :2000/09/08(金) 12:15
37 :
名無しさん@お腹いっぱい。 :2000/09/08(金) 13:30
>表示はそれとして、「くぐり抜けられる橋」みたいなのの
>マップ構造がよくわからない>おれ
>ハイトマップ+フラグじゃないだろうし
>>10にある通り、3次元配列のブロックマップでよござんすよ。
LEGOブロックか積み木みたいな感じにすると思いねぇ。
>内部のデータ構造からクォータービュー描画のための座標を計算することが “ジオメトリ変換”
>です >> バカ31君
さようですか。ご愁傷様。
ケタロウの周りでは、ジオメトリ変換って(x@`y@`z@`w)のベクトルの4x4行列による変換をいうんだよね。ケケケ。
まぁ、世の中広いからね。確認もせずに使った俺が悪かったよ。ケケケ。
>>31 >1 と 2 と 3Dを勧めている人の文脈は全く別。
別にどうでもいいや。おいらのストレス解消の相手になってくれや。ケケケ。
>>#ちなみに後学のため
>って2が言ってるじゃん。
だから、
>>28 で親切丁寧に本を紹介してやっただろ、くそぼけ。
>37
グローバルなマップを3次元配列にすると、メモリ使用量が半端じゃないから、
高さの属性をもつ2次元なマップの上に、3次元のボクセルデータで表現された
オブジェクトを配置するといいね。
地面の上に建物を建てる感じだね。
39 :
gaiya :2000/09/08(金) 20:28
それは貴方の職場仲間や御学友の間でのローカルな呼称ですよね。
行列変換は4x4だろうが2x2だろうが行列変換ですよね。ね。
40 :
39 :2000/09/08(金) 20:56
誤送信スマン。上の付け足し
それ以外の部分は意見同じ。
だって16bit以下の低速マシンで固定少数点で
行列積み重ねるよな処理は避けたいもんな。
そりゃ処理の内容つーか意味は行列で説明した
ほうがスッキリするさ。けど計算は冗長だしょ。
マシンがヘボだとナンバーテンだよ。
で、最適化とか何とか嘘っぽい名目でっち上げて
省いたりスカしたり悪いことするよな。
そりゃ出来上がったコード速いよ。でも超汚いよ。
そんなコード目の前にして
「実はこれ、行列変換しておりまして」
なんて云えないよな。もはや。
とか思た終わり〜
41 :
名無しさん@お腹いっぱい。 :2000/09/08(金) 23:33
ボクセルデータを配置するって、すんごくデータ量おおくならないですか?
それにしても、モデルの表現方法で「ボクセル」っていうのは始めて聞きました。
42 :
>41 :2000/09/10(日) 00:46
初心者の知らなさそうな言葉を使いたかったんでしょ(笑)
どー考えたってデータ量も処理も重くなりそうな気がするのですが、
私が幼稚なだけでしょうか? 教えてくださいませませ>ケタロウ
43 :
名無しさん@お腹いっぱい。 :2000/09/10(日) 02:38
ケタロウ氏ぢゃないが、そもそも例えば20x20x20として8000要素だから
ランドストーカーとかFFT(高速フーリエ変換ちゃうで)程度の
マップサイズなら全然問題ないの出羽山脈。
もっとマップ広げたきゃ、ポインタの2次元配列にでもしなさい。
XY平面上の同じ要素共有できるから、だいぶfoorprint減ると思ー。
44 :
名無しさん@お腹いっぱい。 :2000/09/10(日) 02:41
s/foorprint/footprint/
45 :
1 :2000/09/10(日) 12:14
荒れててレスしにくい・・・
つーか、しょっちゅう荒れるな、この板。
46 :
名無しさん@お腹いっぱい。 :2000/09/10(日) 12:45
ここはもう駄目です。
体は大人でも心は厨房なひとが多すぎます。
1ボクセル=立体マップの1マス(1ブロック)ぐらいで十分だろう。
各マップ要素にそれ以上の詳細度いらんじゃろ。
各ボクセルに、マップ要素に対応するビットマップをテクスチャすればいい。
って、わかんねーだろーなぁ。なんか飽きた。
折角おもしろそうな話題だと思ったけど、ついてくる人いないんだもんなぁ。
48 :
>47 :2000/09/10(日) 15:15
いや、前もそうだったけど、用語の使い方がローカル過ぎない?
たぶん2次元配列に動的配列かリンクリストでつなぐ方式だろうと思うけど
あんたには付いて行きたくないな。
49>47 な、当然だけど。
51 :
名無しさん@お腹いっぱい。 :2000/09/10(日) 19:00
52 :
51 :2000/09/10(日) 19:01
以外と>意外と
欝だし脳
>47
ボクセルがローカルかどうかはさておき、
"たぶん2次元配列に動的配列かリンクリストでつなぐ方式だろうと思うけど"
データ構造を工夫すべし。リンクリストにするとあたり判定が面倒かも。
4x4x4マスを占拠するような大きなキャラクタとか
表現するには"動的配列"ってのも、あんまりうまくないね。
#>49@`50 ご自由に。
54 :
>53 :2000/09/10(日) 20:30
まず、ボクセル(あなたの言う)の説明をしてほしいです。
47は、マップに配置するオブジェクトは、1ボクセル(あなたの言う)
の大きさのブロックを積み上げた形で表現するように書いてありますが、
つまり、マップ内の各ボクセル(あなたのいう)をどのオブジェクトが
占領してるかをデータにする、という意味ですか?
そうするとオブジェクトの形状はそのブロックの組み合わせ+テクスチャー
で表現できるものに限るという事でしょうか?
55 :
名無しさん@お腹いっぱい。 :2000/09/10(日) 21:19
内部構造は別にして、マップデータはやっぱりこれからはXMLでしょうかね
56 :
名無しさん@お腹いっぱい。 :2000/09/10(日) 22:22
最初のほうのケタロウ氏はアレだと思ったが、ここんとこの流れを見るとちょっと援護してみたい感じだ。
とりあえず、voxelって一般用語じゃないの?
2Dのpixelに対して3Dのvoxelやろ?
57 :
名無しさん@お腹いっぱい。 :2000/09/10(日) 22:46
まあ、単なるxyzの配列と言ってしまえばそれまでですが>Voxel
でも、色や透過率が入っているのが普通だと思うから
今回みたくオブジェクト番号とかを入れておくのはボクセルとは
言わないのかもなあ
当り判定用には、bitなフラグだけのボクセルを
持つというのはどうだろう
58 :
名無しさん@お腹いっぱい。 :2000/09/10(日) 22:51
DiabloIIあたりだと、ボクセルじゃないんだろうなあ
59 :
名無しさん@お腹いっぱい。 :2000/09/11(月) 03:41
ボクセルって、レイトレーシングの交差判定に使うとか、
>>57にあるような
ボリュームデータの表現に使うとかいうのが一般的なんだろうね。
4x4x4程度の大きさで「大きなキャラクター」っていう表現になる
と、ちょっと精度が足りなさ過ぎって感じだな。
60 :
59 :2000/09/11(月) 06:12
精度じゃねくて、解像度、だな。
61 :
名無しさん@お腹いっぱい。 :2000/09/11(月) 14:51
ランドストーカーだと、キャラクタとか動く床とか
境界がわからないくらいなめらかに動いてた気がするけど
キャラクタはもっと細かい座標で動いてるということなのかな
固定オブジェクトだけヴォクセルで保持していて
(BGと立体スプライトみたいな?)
それとも、思ってるよりヴォクセルが細かかったのかな
62 :
名無しさん@お腹いっぱい。 :2000/09/11(月) 18:26
>38
>ケタロウの周りでは、ジオメトリ変換って(x@`y@`z@`w)のベクトルの4x4行列による変換をいうんだよね。ケケケ。
まぁ、世の中広いからね。確認もせずに使った俺が悪かったよ。ケケケ。
ふう ほんとにバカだな....
行列を使わずに計算するのは可搬性のためでしょ
クォータービュー固定ならわざわざ行列を生成せずに
計算してもいいけども そのときのX,Y座標を変換するための
パラメーターはどうやって導くの??
もしかして手作業?:DDD
そのときのパラメータは変換行列と同じものになるんじゃないの?
誤>行列を使わずに
正>行列を使って
ゲームなんかで高速にクォータービューを描画したいばあいはさ、
各マスごとにXY座標を変換するなんて無駄なことはしないのさ。
書くマスごとに掛け算なんかしてたら遅くてたまらん。
クォータービューは描画する場所きまってて増分が一定だから、
増分:長さ:ギャップ:増分:長さ...
という風にあらかじめ、計算しておくと、アセンブラも書きやすいし、
高速にできるんじゃ。ケケケ。確かに、半手計算だな。
あらかじめ計算したデータをソースに埋め込むといった荒業だな。
画面の大きさが代わると、手直しがすっごーーーーく大変だけどね。
昔はそのくらいしないと、まともに遊べる代物はできなかったんだよね。
>62 ところでさ可搬性を考えたかったら、なんにも考えずにDirect3Dつかえば?
画面固定なら手作業だわなあ、ふつう
マップはクオータービューだけど、視点が動かせるとか
うざいエフェクトばりばりとか
そういう今風の余計な機能をつければ行列った方がいいのかも
66 :
名無しさん@お腹いっぱい。 :2000/09/11(月) 23:04
ひょっとして割と古いお方なんでしょうか>ケタロウ殿
あたしなら完全に3Dでやって(マップくるくる回したいし)
行列も使って、GTEやらVUやら頂点バッファやらに任せちゃうです。
67 :
66 :2000/09/11(月) 23:05
おおう、ダブった。
でも、ふつうに3Dでやる話なら、このスレッド要らないよね〜
マップや当り判定もポリゴン(BSPしたりして)でやるとかさ〜
ゲームボーイやワンダースワンあたりだと、まだまだ使えるテクニック
だとおもうし>手計算
手計算の方が、おもしろそうで興味深いと思うのは
おいらも古い人間だからでしょうか(ためいき
んでも、とりあえず本題の答えは出ちゃったよーな気が。
>>43 >もっとマップ広げたきゃ、ポインタの2次元配列にでもしなさい。
>XY平面上の同じ要素共有できるから、だいぶfoorprint減ると思ー。
ある種の圧縮ですな。いっそFlyweightパターン……は大げさかなあ。
>>61 >キャラクタはもっと細かい座標で動いてるということなのかな
>固定オブジェクトだけヴォクセルで保持していて
>(BGと立体スプライトみたいな?)
その通りでしょう。
関係ないけど、昔スーパーカセットビジョンのソフトで
マップエディタ(BG式)に置いた壁やハシゴの数に比例して
ゲームスピードが遅くなっていくやつがあった(w
>GTEやらVUやら頂点バッファやらに任せちゃうです。
そのローカルさはどうしたもんでしょう。
ハードの名称並べてアルゴリスムの説明になるなら
このスレは要らんでしょう。赤面ネタはやめちくり。
このスレと関係なくてすまんが、プログラム板の方の、やねうらおのスレで
「除算命令使わないで、どうやって3Dするんだ」とか言ってた人って
3Dって透視投影しかないって思ってたのかな