顯示具有 Sandy3D 標籤的文章。 顯示所有文章
顯示具有 Sandy3D 標籤的文章。 顯示所有文章

2009年8月31日 星期一

Tutorial 04b - Sprite2D

Sprite2D - 一個簡化版的顯示方示,用以取代 3D 顯示物件,可以省去許多額外的計算及資源。此物件在場景中,永遠是面對著 Camera 的。舉例來說,天上的星星、水中的魚、森林裡的樹,都可以利用 Sprite2D 來顯示。

重點API:
sandy.util.LoaderQueue
sandy.core.scenegraph.Sprite2D
sandy.events.QueueEvent

  1. package
  2. {
  3. import flash.display.Bitmap;
  4. import flash.display.Sprite;
  5. import flash.events.Event;
  6. import flash.events.KeyboardEvent;
  7. import flash.events.MouseEvent;
  8. import flash.net.URLRequest;
  9. import sandy.core.Scene3D;
  10. import sandy.core.scenegraph.Camera3D;
  11. import sandy.core.scenegraph.Group;
  12. import sandy.core.scenegraph.Sprite2D;
  13. import sandy.events.QueueEvent;
  14. import sandy.util.LoaderQueue;

  15. public class Example004b extends Sprite
  16. {
  17. private var scene:Scene3D;
  18. private var camera:Camera3D;
  19. // Utility class for 載入外部資源
  20. private var queue:LoaderQueue;
  21. /** numTree 將影響 CPU 的效能 **/
  22. private var numTree:Number = 50;
  23. public function Example004b()
  24. {
  25. // 產生一 LoaderQueue 物件
  26. queue = new LoaderQueue();
  27. // 將欲載入資源之Unique名稱及路徑,加入 queue 中
  28. queue.add("tree", new URLRequest("asset/tree.gif"));
  29. // 為 queue 物件新增監聽事件 - 當資源載入完成時,
  30. // 執行 loadComplete Function
  31. queue.addEventListener(
  32. QueueEvent.QUEUE_COMPLETE,
  33. loadComplete);
  34. // 為 queue 物件新增監聽事件 - 當載入資源發生錯誤時,
  35. // 執行 loadError Function
  36. queue.addEventListener(
  37. QueueEvent.QUEUE_LOADER_ERROR,
  38. loadError);
  39. // 開始載入外部資源
  40. queue.start();
  41. }

  42. public function loadComplete(evt:QueueEvent):void
  43. {
  44. // 產生 Camera3D 物件
  45. camera = new Camera3D(600, 300);
  46. camera.y = 10;
  47. camera.z = -300;

  48. // 產生 Group 物件
  49. var root:Group = createScene();

  50. // 產生 Scene3D 物件,並將 Camera3D 及 Group 加入場景
  51. scene = new Scene3D("scene", this, camera, root);
  52. // 設定當物件超出場景之外時,將不會被畫出
  53. scene.rectClipping = true;

  54. addEventListener(Event.ENTER_FRAME,
  55. enterFrameHandler);
  56. stage.addEventListener(KeyboardEvent.KEY_DOWN,
  57. keyPressHandler);
  58. stage.addEventListener(MouseEvent.MOUSE_MOVE,
  59. mouseMoveHandler);
  60. }

  61. public function loadError(evt:QueueEvent):void
  62. {
  63. trace("load resource error");
  64. }

  65. private function createScene():Group
  66. {
  67. // 產生根 Group 物件
  68. var g:Group = new Group();

  69. // 產生 Sprite2D 物件
  70. for (var i:Number = 0; i <>
  71. {
  72. // 將載入 queue 物件中的資源取出
  73. var bit:Bitmap =
  74. new Bitmap(queue.data["tree"].bitmapData);
  75. // 產生 Sprite2D 物件,並設置其參數,分別為
  76. // Unique名稱,顯示物件 (DisplayObject) 及 縮放比率
  77. var s:Sprite2D = new Sprite2D("tree" + i, bit, 1);
  78. // 隨機設定 Sprite2D 的 x, y, z 座標位置
  79. s.x = Math.random() * 600 - 300;
  80. s.y = 0;
  81. s.z = Math.random() * 600;

  82. g.addChild(s);
  83. }

  84. return g;
  85. }
  86. private function enterFrameHandler(evt:Event):void
  87. {
  88. scene.render();
  89. }
  90. private function keyPressHandler(evt:KeyboardEvent):void
  91. {
  92. // 調整 camera 鏡頭之遠近
  93. switch(evt.keyCode)
  94. {
  95. case KeyboardEvent.KEY_UP:
  96. camera.moveForward(5);
  97. break;
  98. case KeyboardEvent.KEY_DOWN:
  99. camera.moveForward( -5);
  100. break;
  101. }
  102. }
  103. private function mouseMoveHandler(evt:MouseEvent):void
  104. {
  105. // 隨滑鼠移動設置 camera 之方向
  106. camera.pan = (evt.stageX - 300 / 2) / 10;
  107. camera.tilt = (evt.stageY - 300 / 2) / 20;
  108. }
  109. }
  110. }




程式碼出處:http://www.flashsandy.org/tutorials/3.0/sandy_cs3_tut042

2009年7月22日 星期三

Tutorial 04a - 燈光的使用

重點API:
sandy.primitive.Box;
sandy.primitive.Cylinder;
sandy.primitive.PrimitiveMode;
sandy.primitive.Sphere;


  1. package
  2. {
  3. import flash.display.Sprite;
  4. import flash.events.Event;
  5. import flash.events.KeyboardEvent;
  6. import flash.ui.Keyboard;
  7. import sandy.core.Scene3D;
  8. import sandy.core.scenegraph.Camera3D;
  9. import sandy.core.scenegraph.Group;
  10. import sandy.core.scenegraph.TransformGroup;
  11. import sandy.materials.Appearance;
  12. import sandy.materials.attributes.CylinderEnvMap;
  13. import sandy.materials.attributes.LightAttributes;
  14. import sandy.materials.attributes.LineAttributes;
  15. import sandy.materials.attributes.MaterialAttributes;
  16. import sandy.materials.ColorMaterial;
  17. import sandy.materials.Material;
  18. import sandy.primitive.Box;
  19. import sandy.primitive.Cylinder;
  20. import sandy.primitive.PrimitiveMode;
  21. import sandy.primitive.Sphere;
  22. public class Example004a extends Sprite
  23. {
  24. private var scene:Scene3D;
  25. private var camera:Camera3D;
  26. private var tg:TransformGroup;
  27. // 設定燈光 x, y, z 軸參數
  28. private var lightX:Number = 0;
  29. private var lightY:Number = 0;
  30. private var lightZ:Number = 10;
  31. public function Example004a()
  32. {
  33. camera = new Camera3D(300, 300);
  34. camera.z = -400;
  35. var root:Group = createScene();
  36. scene = new Scene3D("scene", this, camera, root);
  37. // 設定場景燈光的方向位置
  38. scene.light.setDirection(lightX, lightY, lightZ);
  39. addEventListener(Event.ENTER_FRAME,
  40. enterFrameHandler);
  41. stage.addEventListener(KeyboardEvent.KEY_DOWN,
  42. keyPressed);
  43. }
  44. private function createScene():Group
  45. {
  46. var g:Group = new Group();
  47. tg = new TransformGroup();
  48. var materialAttr:MaterialAttributes =
  49. new MaterialAttributes(
  50. new LineAttributes(0, 0x2111BB, 0),
  51. new LightAttributes(true, 0.1)
  52. );
  53. var material:Material = new ColorMaterial(
  54. 0xFFCC33, 1, materialAttr
  55. );
  56. material.lightingEnable = true;
  57. var app:Appearance = new Appearance(material);
  58. var materialAttr2:MaterialAttributes =
  59. new MaterialAttributes(
  60. new LineAttributes(0, 0x2111BB, 0),
  61. new LightAttributes(true, 0.1)
  62. );
  63. var material2:Material = new ColorMaterial(
  64. 0xCC0000, 1, materialAttr
  65. );
  66. material2.lightingEnable = true;
  67. var app2:Appearance = new Appearance(material2);
  68. var materialAttr3:MaterialAttributes =
  69. new MaterialAttributes(
  70. new LineAttributes(0, 0x2111BB, 0),
  71. new LightAttributes(true, 0.1)
  72. );
  73. var material3:Material = new ColorMaterial(
  74. 0x008AE6, 1, materialAttr
  75. );
  76. material3.lightingEnable = true;
  77. var app3:Appearance = new Appearance(material3);
  78. // 產生一 Box 物件,並設定其參數,分別為:
  79. // 識別名稱、寬、高、深度、face generation 及 Quility
  80. var table:Box = new Box(
  81. "table", 10, 150, 200, PrimitiveMode.QUAD, 1
  82. );
  83. //table.enableBackFaceCulling = false;
  84. // 設定是否容許使用者改變呈現此 table 的方式
  85. table.useSingleContainer = false;
  86. // 設定 table 的外觀
  87. table.appearance = app;
  88. // 旋轉 table
  89. table.rotateY = 90;
  90. table.rotateX = 90;
  91. // 產生一 Cylinder 物件,並設定其參數,分別為
  92. // 識別名稱、半徑及高
  93. var leg01:Cylinder = new Cylinder("leg01", 5, 80);
  94. // 設定 leg01 的外觀
  95. leg01.appearance = app;
  96. // 設定 leg01 的 x,y,z 座標
  97. leg01.x = -80;
  98. leg01.y = -45;
  99. leg01.z = 50;
  100. var leg02:Cylinder = new Cylinder("lig02", 5, 80);
  101. leg02.appearance = app;
  102. leg02.x = 80;
  103. leg02.y = -45;
  104. leg02.z = 50;
  105. var leg03:Cylinder = new Cylinder("leg03", 5, 80);
  106. leg03.appearance = app;
  107. leg03.x = -80;
  108. leg03.y = -45;
  109. leg03.z = -50;
  110. var leg04:Cylinder = new Cylinder("leg04", 5, 80);
  111. leg04.appearance = app;
  112. leg04.x = 80;
  113. leg04.y = -45;
  114. leg04.z = -50;
  115. // 產生一 Sphere 物件,並設定其參數,分別為:
  116. // 識別名稱、半徑、水平切割數及垂直切割數
  117. var mySphere:Sphere = new Sphere("theSphere", 20, 20, 8);
  118. mySphere.useSingleContainer = true;
  119. mySphere.appearance = app2;
  120. mySphere.y = 25;
  121. mySphere.x = -30;
  122. var myBox:Box = new Box(
  123. "theBox", 60, 60, 60, PrimitiveMode.TRI, 3
  124. );
  125. myBox.useSingleContainer = true;
  126. myBox.appearance = app3;
  127. myBox.rotateY = 30;
  128. myBox.x = 40;
  129. myBox.y = 35;
  130. tg.addChild(table);
  131. tg.addChild(leg01);
  132. tg.addChild(leg02);
  133. tg.addChild(leg03);
  134. tg.addChild(leg04);
  135. tg.addChild(mySphere);
  136. tg.addChild(myBox);
  137. tg.rotateX = 5;
  138. g.addChild(tg);
  139. return g;
  140. }
  141. private function enterFrameHandler(evt:Event):void
  142. {
  143. // 將場景顯示快取設定為 false
  144. scene.render(false);
  145. }
  146. private function keyPressed(evt:KeyboardEvent):void
  147. {
  148. switch(evt.keyCode)
  149. {
  150. case Keyboard.PAGE_DOWN:
  151. // 減少場景燈光的亮度
  152. scene.light.setPower(scene.light.getPower() - 5);
  153. break;
  154. case Keyboard.PAGE_UP:
  155. // 增加場景燈光的亮度
  156. scene.light.setPower(scene.light.getPower() + 5);
  157. break;
  158. case Keyboard.UP:
  159. lightY += 10;
  160. scene.light.setDirection(lightX, lightY, lightZ);
  161. break;
  162. case Keyboard.DOWN:
  163. lightY -= 10;
  164. scene.light.setDirection(lightX, lightY, lightZ);
  165. break;
  166. case Keyboard.RIGHT:
  167. lightX += 10;
  168. scene.light.setDirection(lightX, lightY, lightZ);
  169. break;
  170. case Keyboard.LEFT:
  171. lightX -= 10;
  172. scene.light.setDirection(lightX, lightY, lightZ);
  173. break;
  174. }
  175. }
  176. }
  177. }


產出:



程式碼出處:http://www.flashsandy.org/tutorials/3.0/sandy_cs3_tut041

2009年7月14日 星期二

Tutorial 04 - Start Moving

重點API:
sandy.core.scenegraph.TransformGroup
sandy.primitive.Cone
sandy.primitive.Hedra


  1. package
  2. {
  3. import flash.display.Sprite;
  4. import flash.events.*;
  5. import flash.ui.*;
  6. import sandy.core.Scene3D;
  7. import sandy.core.data.*;
  8. import sandy.core.scenegraph.*;
  9. import sandy.materials.*;
  10. import sandy.materials.attributes.*;
  11. import sandy.primitive.*;
  12. public class Example004 extends Sprite
  13. {
  14. private var scene:Scene3D;
  15. private var camera:Camera3D;
  16. private var tg:TransformGroup;
  17. private var myCone:Cone;
  18. private var myHeadra:Hedra;
  19. public function Example004()
  20. {
  21. // 產生 camera 物件
  22. camera = new Camera3D(300, 300);
  23. camera.x = 100;
  24. camera.y = 100;
  25. camera.z = -400;
  26. camera.lookAt(0, 0, 0);
  27. // 產生顯示物件群組
  28. var root:Group = createScene();
  29. // 產生場景物件,並將 camera 物件及顯示
  30. // 物件群組加到場景中
  31. scene = new Scene3D("scene", this, camera, root);
  32. addEventListener(Event.ENTER_FRAME, enterFrameHandler);
  33. stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
  34. }
  35. private function createScene():Group
  36. {
  37. var g:Group = new Group();
  38. // 在每個座標軸,產生一線性物件
  39. var myXLine:Line3D = new Line3D("x-coord", new Point3D(-50, 0, 0),
  40. new Point3D(50, 0, 0));
  41. var myYLine:Line3D = new Line3D("y-coord", new Point3D(0, -50, 0),
  42. new Point3D(0, 50, 0));
  43. var myZLine:Line3D = new Line3D("z-coord", new Point3D(0, 0, -50),
  44. new Point3D(0, 0, 50));
  45. // 產生一移動群組物件, 並為其命名
  46. tg = new TransformGroup("myGroup");
  47. // 產生Cone object, 並設定其參數,分別為:
  48. // 識別名稱, 半徑及高
  49. myCone = new Cone("theObj1", 50, 100);
  50. // 產生 Hedra objecct,並設定其參數,分別為:
  51. // 識別名稱、高、寬及深度
  52. myHeadra = new Hedra("theObj2", 80, 60, 60);
  53. // 分別將 Cone 物件移到左邊, Hedra 物件移到右邊
  54. myCone.x = -160;
  55. myCone.z = 150;
  56. myHeadra.x = 90;
  57. // 產生 materialAttributes物件
  58. var materialAttr:MaterialAttributes = new MaterialAttributes(
  59. new LineAttributes(0.5, 0x2111BB, 0.4),
  60. new LightAttributes(true, 0.1)
  61. );
  62. var material:Material = new ColorMaterial(0xFFCC33, 1, materialAttr);
  63. material.lightingEnable = true;
  64. var app:Appearance = new Appearance(material);
  65. myCone.appearance = app;
  66. myHeadra.appearance = app;
  67. // 將兩個 objects 加入移動群組物件中
  68. tg.addChild(myCone);
  69. tg.addChild(myHeadra);
  70. // 將所有的物件加入 Group 物件中
  71. g.addChild(tg);
  72. g.addChild(myXLine);
  73. g.addChild(myYLine);
  74. g.addChild(myZLine);
  75. return g;
  76. }
  77. private function enterFrameHandler(evt:Event):void
  78. {
  79. // 調整 Headra 與 Cone 沿Y軸轉向的幅度
  80. myHeadra.pan += 4;
  81. myCone.pan += 4;
  82. scene.render();
  83. }
  84. private function keyPressed(evt:KeyboardEvent):void
  85. {
  86. switch(evt.keyCode)
  87. {
  88. case Keyboard.UP:
  89. tg.y += 2;
  90. break;
  91. case Keyboard.DOWN:
  92. tg.y -= 2;
  93. break;
  94. case Keyboard.RIGHT:
  95. tg.roll += 2;
  96. break;
  97. case Keyboard.LEFT:
  98. tg.roll -= 2;
  99. break;
  100. }
  101. }
  102. }
  103. }

產出:



程式碼出處:http://www.flashsandy.org/tutorials/3.0/sandy_cs3_tut04

2009年6月24日 星期三

Tutorial 03a: Camera 與 Screen Resize

在Sandy3D裡Camera有一屬性, fov (vertical field of view angle),代表了垂直視野的視角與視點高度的關係,如下圖所示:

focal length的計算公式為:
var fl:Numer = (viewport.height / 2) / Math.tan (camera.fov / 2 * (Math.PI / 180));
任何位於 wz = fl 的 plane 後面的物體,看起來都會比實際上小,而位於前面的,就會看起來比較大。

  1. package
  2. {
  3. import flash.display.Bitmap;
  4. import flash.display.BitmapData;
  5. import flash.display.Sprite;
  6. import flash.display.StageScaleMode;
  7. import flash.display.StageAlign;
  8. import flash.events.Event;
  9. import sandy.core.scenegraph.Camera3D;
  10. import sandy.core.scenegraph.Group;
  11. import sandy.materials.Appearance;
  12. import sandy.materials.BitmapMaterial;
  13. import sandy.primitive.Plane3D;
  14. import sandy.core.Scene3D;

  15. public class Example003a extends Sprite
  16. {
  17. [Embed(source = 'images/Ume.png')]
  18. private var texture:Class;
  19. private var scene:Scene3D;
  20. private var plane:Plane3D;
  21. public function Example003a()
  22. {
  23. var text:Bitmap = new texture;
  24. var tex:BitmapData = text.bitmapData;
  25. stage.scaleMode = StageScaleMode.NO_SCALE;
  26. stage.align = StageAlign.TOP_LEFT;
  27. scene = new Scene3D("myScene", this, new Camera3D(100, 100),
  28. new Group("myRoot"));
  29. // 產生一 Plane3D 物件,並設定其參數, 分別為:
  30. // 識別名稱,寬與高
  31. plane = new Plane3D("myPlane", tex.height, tex.width);
  32. // 設定 plane 之外觀
  33. plane.appearance = new Appearance(new BitmapMaterial(tex));
  34. scene.root.addChild(plane);
  35. scene.render();
  36. stage.addEventListener(Event.RESIZE, onResize);
  37. onResize(null);
  38. }
  39. private function onResize(evt:Event):void
  40. {
  41. // 取得舞台的寬及高
  42. var w:Number = stage.stageWidth;
  43. var h:Number = stage.stageHeight;
  44. // 更新攝影機的視點
  45. scene.camera.viewport.width = w;
  46. scene.camera.viewport.height = h;
  47. // 取得 plane 與攝影機的距離
  48. var d:Number = plane.getPosition("camera").getNorm();
  49. // 將攝影機的焦點置於 wz = d 並維持1:1大小
  50. scene.camera.fov = 2 * Math.atan2(h / 2, d) * (180 / Math.PI);
  51. // 刷新場景
  52. scene.render();
  53. }
  54. }
  55. }



程式碼出處:http://www.flashsandy.org/tutorials/3.0/sandy_cs3_tut03a

2009年6月17日 星期三

Tutorial 03: 使用Camera3D

重點API:
sandy.core.scenegraph.Camera3D
sandy.core.data.Point3D
sandy.primitive.Line3D
sandy.primitive.Torus
  1. package
  2. {
  3. import flash.display.InteractiveObject;
  4. import flash.display.Sprite;
  5. import flash.events.Event;
  6. import flash.events.KeyboardEvent;
  7. import flash.ui.Keyboard;
  8. import sandy.core.data.Point3D;
  9. import sandy.core.Scene3D;
  10. import sandy.core.scenegraph.Camera3D;
  11. import sandy.core.scenegraph.Group;
  12. import sandy.materials.Appearance;
  13. import sandy.materials.attributes.LightAttributes;
  14. import sandy.materials.attributes.LineAttributes;
  15. import sandy.materials.attributes.MaterialAttributes;
  16. import sandy.materials.ColorMaterial;
  17. import sandy.materials.Material;
  18. import sandy.primitive.Line3D;
  19. import sandy.primitive.Torus;
  20. public class Example003 extends Sprite
  21. {
  22. private var scene:Scene3D;
  23. private var camera:Camera3D;
  24. public function Example003()
  25. {
  26. camera = new Camera3D(300, 300);
  27. //camera.x = 100;
  28. //camera.y = 100;
  29. camera.z = -400;
  30. // 使得 camera 物件朝某點拍攝
  31. //camera.lookAt(0, 0, 0);
  32. var root:Group = createScene();
  33. scene = new Scene3D("scene", this, camera, root);
  34. addEventListener(Event.ENTER_FRAME, enterFrameHandler);
  35. // 為整個舞台添加鍵盤的 Key Down 事件聆聽器
  36. stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
  37. }
  38. private function createScene():Group
  39. {
  40. var g:Group = new Group();
  41. // 產生 3DLine 物件, 並設定其參數,分別為:
  42. // 識別名稱,及 Point3D 物件以定議線條的折點
  43. var myXLine:Line3D = new Line3D("x-coord", new Point3D( -50, 0, 0),
  44. new Point3D(50, 0, 0));
  45. var myYLine:Line3D = new Line3D("y-coord", new Point3D(0, -50, 0),
  46. new Point3D(0, 50, 0));
  47. var myZLine:Line3D = new Line3D("z-coord", new Point3D(0, 0, -50),
  48. new Point3D(0, 0, 50));
  49. // 產生 Torus 物件,並設定其參數,分別為:
  50. // 識別名稱、大半徑及小半徑
  51. var torus:Torus = new Torus("theTorus", 120, 20);
  52. var materialAttr:MaterialAttributes = new MaterialAttributes(
  53. new LineAttributes(0.5, 0x2111BB, 0.4),
  54. new LightAttributes(true, 0.1)
  55. );
  56. var material:Material = new ColorMaterial(0xFFCC33, 1, materialAttr);
  57. material.lightingEnable = true;
  58. var app:Appearance = new Appearance(material);
  59. // 將外觀物件套用到顯示物件 tours
  60. torus.appearance = app;
  61. torus.rotateX = 30;
  62. torus.rotateY = 30;
  63. // 將顯示物件加入舞台顯示群組中
  64. g.addChild(myXLine);
  65. g.addChild(myYLine);
  66. g.addChild(myZLine);
  67. g.addChild(torus);
  68. return g;
  69. }
  70. private function enterFrameHandler(evt:Event):void
  71. {
  72. scene.render();
  73. }
  74. private function keyPressed(evt:KeyboardEvent):void
  75. {
  76. // 依據使用者所按下的鍵,做不用的處理
  77. switch(evt.keyCode) {
  78. case Keyboard.UP:
  79. // 調整 camera 傾斜的幅度
  80. camera.tilt += 2;
  81. break;
  82. case Keyboard.DOWN:
  83. camera.tilt -= 2;
  84. break;
  85. case Keyboard.RIGHT:
  86. // 調整 camera 沿Y軸轉向的幅度
  87. camera.pan -= 2;
  88. break;
  89. case Keyboard.LEFT:
  90. camera.pan += 2;
  91. break;
  92. case Keyboard.CONTROL:
  93. // 調整 camera 沿Z軸卷動的幅度
  94. camera.roll += 2;
  95. break;
  96. case Keyboard.PAGE_DOWN:
  97. // 調整 camera 鏡頭的遠近幅度
  98. camera.z -= 5;
  99. break;
  100. case Keyboard.PAGE_UP:
  101. camera.z += 5;
  102. break;
  103. }
  104. }
  105. }
  106. }

產出:



程式碼出處:http://www.flashsandy.org/tutorials/3.0/sandy_cs3_tut03