I. Giới thiệu Java 3D API
1.Thư viện Java 3D API
Không có sẵn trong Java framework tiêu chuẩn, do đó cần phải cài đặt riêng.
Chứa trên 100 class trong thư viện lõi javax.media.j3d.
Thư viện mức cao: dùng lập trình hướng đối tượng
Có thể thực hiện các công việc mức thấp thông qua OpenGL
Có thể chạy trên nhiều hệ điều hành khác nhau
2.Biến đổi hình học trong Java 3D
Class Transform3D lưu phép biến đổi dưới dạng ma trận (hệ toạ độ thuần nhất)
Hàm tạo:
Transform3D tf=new Transform3D();
a.Phép quay
• tf.rotX(theta): phép quay góc theta quanh trục X
• tf. rotY(theta): phép quay góc theta quanh trục Y
• tf. rotZ(theta): phép quay góc theta quanh trục Z
• tf.set(new AxisAngle4d(x, y, z, theta): phép quay góc theta quanh trục theo hướng vector float(x, y, z)
b.Phép tịnh tiến
tf.setTranslation(new Vector3f(x, y, z)) //vector tịnh tiến (float): (x, y, z).
c.Phép tỉ lệ
Đồng nhất (hệ số tỉ lệ bằng nhau cho cả 3 hướng):
tf.setScale(factor) //hệ số tỉ lệ chung: factor.
Hệ số tỉ lệ có thể khác nhau cho 3 hướng:
tf.setScale(new Vector3f(x, y, z));
d.Phép biến đổi bất kỳ
tf.set(matrix); //matrix: array 1 chiều gồm 16 số double
e.Kết hợp hai phép biến đổi liên tiếp (phép nhân ma trận):
tf.mul(tf1, tf2);
tf1.mul(tf2);
3.Các đối tượng hình học sơ cấp
-Gồm 2 khía cạnh: Appearance và Geometry.
-Class Appearance xác định các thuộc tính bề mặt của đối tượng
Hàm tạo:
myApp = new Appearance();
Gán thuộc tính:
Color3f red = new Color3f(0.8f, 0.0f, 0.0f);
myApp.setMaterial(new Material(red, red, red, red, 150.0f);
Có thể gán giá trị cho Material:
Material myMat = new Material();
myMat.setAmbientColor(0.3f, 0.3f, 0.3f); //Bao quanh
myMat.setEmissiveColor(0.0f, 0.0f, 0.0f); //Phát xạ
myMat. setDiffuseColor(1.0f, 0.0f, 0.0f); //Khuyếch tán
myMat. setSpecularColor(1.0f, 1.0f, 1.0f); //Phản chiếu
myMat. setShininessColor(64.0f); // Độ bóng
Hình hộp:
Box xyzBox = new Box(x, y, z, myApp);
Kích thước 2*x, 2*y, 2*z. Tâm box tại gốc hệ tọa độ
Hình cầu:
Sphere rSphere = new Sphere(r, myApp);
Bán kính r. Tâm tại gốc hệ tọa độ.
Hình trụ:
Cylinder rhCyl = new Cylinder(r, h, myApp);
Bán kính r, chiều cao h. Tâm tại gốc hệ tọa độ.
Hình nón:
Cone rhCone = new Cone(r, h, myApp);
Bán kính r, chiều cao h. Tâm tại gốc hệ tọa độ.
Mặc định: x = y = z = r = h/2 = 1mét; Color: white
4.Scenegraph trong Java 3D
Scenegraph là một cấu trúc dữ liệu dạng cây dùng lưu trữ tất cả các thông tin cần thiết để hiển thị cảnh 3D (bao gồm hoạt hình, tương tác).
Giúp lập trình trong Java 3D nhanh hơn nhiều so với OpenGL hay DirectX.
Dạng khái quát:
Content Branch chứa các đối tượng hình học (mô hình 3D) trong cảnh (bao gồm hoạt hình).
Lights chịu trách nhiệm chiếu sáng cảnh.
View Branch (View Platform) qui định các tham số quan sát như vị trí mắt người xem, hướng xem, kiểu phép chiếu, …
+ SimpleUniverse là VirtualUniverse tối thiểu.
+ SimpleUniverse cung cấp View Platform mặc định, người lập trình không phải qui định tất cả tham số. Nhờ đó giảm gánh nặng xử lí nhánh này.
5. Chương trình Java 3D với SimpleUniverse
Các bước:
-Tạo một Canvas3D.
-Tạo một SimpleUniverse tham chiếu đến Canvas3D.
Điều chỉnh SimpleUniverse, nếu muốn.
-Xây dựng Content Branch.
-Compile Content Branch.
-Add Content Branch vào Local của SimpleUniverse.
import …
public class MyJava3Dclass extends JFrame
{
public Canvas3D myCanvas3D;
public MyJava3Dclass()
{
…
}
public static void main(String[] args)
{
MyJava3Dclass myJava3D = new MyJava3Dclass();
}
}
Public MyJava3Dclass()
{
myCanvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
SimpleUniverse simpUniv = new SimpleUniverse(myCanvas3D);
simpUniv.getViewingPlatform().setNominalViewingTransform();
createSceneGraph(simpUniv); //tạo và sắp các đối tượng hình học của cảnh
addLight(simpUniv); //chiếu sáng các đối tượng hình học của cảnh
OrbitBehavior ob = new OrbitBehavior(myCanvas3D);
Ob.setSchedulingBounds( new BoundingSphere( new Point3d(0.0, 0.0, 0.0), Double.MAX_VALUE));
SimpUniv.getViewingPlatform().setViewPlatformBehavior(ob);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Java 3D with SimpleUniverse");
setSize(700,700);
getContentPane().add("Center",myCanvas3D);
setVisible(true);
}
6. Nhánh nội dung (Content Branch)
Content Branch có cấu trúc cây, tạo bởi phương thức createSceneGraph. Phương thức này tạo ra các đối tượng hình học và sắp xếp chúng trong cảnh.
Root của Content Branch được sinh bởi:
BranchGroup theScene = new BranchGroup();
Phương thức theScene.addChild(node) dùng để gắn node thành con của Root.
Ví dụ:
Phần của scenegraph ứng với nhánh Nội dung:
Node lá là:
-Đối tượng hình học 3D (như cabin, tail, …).
-Phép biến đổi (transformation), như các node tf.
Node trong là nhóm biến đổi (transformation group), như các node tg.
Nhóm biến đổi
Mỗi nhóm biến đổi có:
-Tối đa 1 con là 1 phép biến đổi( kết hợp hay đơn).
-Các con còn lại là node trong hay node lá đối tượng hình học.
-Phép biến đổi (trong 1 node con, nếu có) áp dụng cho các node con còn lại.
Các nhón biến đổi (các node con) được kết hợp lại thành đối tượng phức tạp hơn (node cha) để định vị và xử lí như 1 đối tượng đơn.
Một phép biến đổi áp dụng lên node cha thì tự động áp dụng lên các node con (lan truyền thuộc tính).
8. Di chuyển trong cảnh
Thêm các dòng code sau để có thể dùng chuột di chuyển trong cảnh:
OrbitBehavior ob = new OrbitBehavior(myCanvas3D);
Ob.setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0), Double.MAX_VALUE)); simpUniv.getViewingPlatform().setViewPlatformBehavior(ob);
II. Hoạt hình, tương tác, chiếu sáng với Java 3D
1. Class Behavior, class Alpha, class Interpolator
Class Behavior (Hành vi)
Là cơ sở cho tương tác (interaction) và hoạt hình (animation).
Tương tác: thay đổi cảnh do điều kiện của người dùng (bàn phím, chuột).
Hoạt hình: thay đổi cảnh do điều khiển của thời gian.
Class Alpha (Hàm theo thời gian)
Quá trình nội suy được điều khiển theo thời gian thông qua class Alpha.
Đối tượng Alpha xác định 1 hàm sản sinh giá trị từ 0 đến 1 và tuần hoàn theo thời gian.
Nhịp điệu thời gian của Alpha không đều đặn như đồng hồ thời gian thực, mà được người lập trình điều chỉnh bằng nhiều tham số truyền cho Alpha.
Tùy theo các tham số truyền, giá trị Alpha có đồ thị dạng sóng khác nhau.
Class Interpolator
Để thực hiện hoạt hình một đối tượng mục tiêu (target), người lập trình xác định 2 hay nhiều giá trị mục tiêu để làm mốc: giá trị tại lúc đầu và tại lúc kết thúc hoạt hình. Interpolator sẽ nội suy các giá trị trung gian giữa hai giá trị mốc.
Mục tiêu hoạt hình là thuộc tính nào đó của mô hình 3D như: vị trí, hướng, kích cỡ, màu, …
Interpolator : ánh xạ các giá trị
- Một bô nội suy dùng hai ánh xạ:
Giá trị thời gian ® giá trị Alpha
Giá trị Alpha ® giá trị của mục tiêu hoạt hình.
- Ví dụ với một hoạt hình tịnh tiến đối tượng hình học từ vị trí đầu tiên đến vị trí cuối:
Người lập trình qui định:
Thời điểm đầu « giá trị alpha đầu (0 hay 1 …) « vị trí đầu.
Thời điểm cuối « giá trị alpha cuối (0 hay 1 …) « vị trí cuối.
Interpolator nội suy:
Với mỗi thời điểm giữa đầu và cuối ® giá trị Alpha ® vị trí tương ứng: dựa vào đồ thị của Alpha, vị trí đầu, vị trí cuối.
Các phương thức tạo của Alpha
public Alpha(int loopCount, int mode, long triggerTime, long phaseDelayDuration, long increasingAlphaDuration, long increasingAlphaRampDuration, long alphaAtOneDuration, long decreaingAlphaDuration, long dereasingAlphaRampDuration, long alphaAtZeroDuration)
public Alpha() // mode = INCREASING_ENABLE, loopCount = -1 (lặp mãi)
// increasingAlphaDuration = 1000 (ms), các tham số khác = 0
public Alpha( int loopCount, long triggertime, long phaseDelayDuration, long increasingAlphaDuration, long increasingAlphaRampDuration, long alphaAtOneDuration)
public Alpha(int loopCount, long increasingAlphaDuration)
Các phương thức Set của Alpha
- void setStartTime(long millisecs)
- void setTriggerTime(long millisecs)
- void setLoopCount(int count)
- void setMode(int mode)
- void setAlphaAtOneDuration(long millisecs)
- void set AlphaAtZeroDuration(long millisecs)
- void setDecreasingAlphaDuration(long millisecs)
- void set DecreasingAlphaRampDuration(long millisecs)
- void setIncreasingAlphaDuration(long millisecs)
- void setIncreasingAlphaRampDuration(long millisecs)
- void setPhaseDelayDuration(long millisecs)
2. Các kiểu Interpolator
Kiểu đơn giản: nội suy từ hai giá trị (đầu và cuối, do người lập trình qui định) của đối tượng mục tiêu. Gồm các kiểu:
- Biến đổi (hình học) đơn: PositionInterpolator, RotationInterpolator, ScaleInterpolator.
- ColorInterpolator, TransparencyInterpolator.
- SwitchValueInterpolator.
Kiểu quĩ đạo: nội suy từ nhiều giá trị của đối tượng mục tiêu, để tạo một “quỹ đạo” tùy ý. Gồm có:
- Biến đổi đơn, quỹ đạo thẳng gấp khúc: PositionPathInterpolator, RotationPathInterpolator.
- Biến đổi kết hợp, quỹ đạo thẳng gấp khúc: RotPosPathInterpolator and RotPosScalePathInterpolator
- Quỹ đạo đường cong: _ SplinePathInterpolator
3. Đối tượng mục tiêu của Interpolator
Mỗi Interpolator có một đối tượng mục tiêu để viết các giá trị mới lên đó.
Đối tượng mục tiêu của từng kiểu Interpolator như sau:
- Các Interpolator biến đổi hình học: TransformGroup.
- ColorInterpolator: Material.
- SwitchValueInterpolator: Switch.
- …
4. PathInterpolator
Các giá trị alpha được qui định bằng một chuỗi các số thực từ 0 đến 1, được gọi là các knot.
Các giá trị của đối tượng mục tiêu được qui định bằng một chuỗi hay nhiều chuỗi: chuỗi các điểm định vị trí, chuỗi các góc quay, chuỗi các hệ số tỉ lệ; chuỗi các keyframe. Chuỗi tạo nên một đường.
Số lượng các knot = số lượng các giá trị trong mot64 chuỗi giá trị của mục tiêu.
Các giá trị trung gian của hai điểm kế cận được nội suy tuyến tính từ 2 điểm đó.
5. Tạo hoạt hình dùng đối tượng Interpolator và Alpha
Public BranchGroup createSceneGraph()
{
BranchGroup objRoot = new BranchGroup(); //tạo 1 branchGroup
//1.tạo đối tượng mục tiêu với Capabilities thích hợp
TransformationGroup objSpin = new TransformationGroup();
objSpin.setCapability(TransformationGroup.ALLOW_TRANSFORM_WRITE);
//2.tạo đối tượng Alpha
Alpha alpha = new Alpha(-1, 60000); //hoạt hình liên tục trong 60s
//3.tạo đối tượng Interpolator tham chiếu đến đối tượng Alpha và đối tượng mục tiêu
RotationInterpolator rotInt = new RotationInterpolator(alpha, objSpin);
//4.gán scheduling bounds cho đối tượng Interpolator vào node thích hợp trên scene graph
objRoot.addChild(objSpin);
objSpin.addChild(new Clock());
objRoot.addChild(rotInt);
objRoot.compile(); //compile scene graph
return objRoot;
}
6. Tương tác
MouseBehavior:
- Dùng thao tác chuột tác động lên đối tượng TransformGroup.
- Ví dụ: MoveGlobe.java
View Platform Behaviors:
- Hỗ trợ tương tác với ViewPlatform (ví dụ để thay đổi hệ quan sát).
- Ví dụ: MoveView.java
KeyNavigatorBehavior:
- Dùng thao tác bàn phím tác động lên đối tượng TransformGroup.
- Ví dụ: TestKeyBehavior.java
PickMouseBehavior
- Hổ trợ dùng chuột chọn đối tượng trong cảnh đang hiển thị.
- Ví dụ: TestPickBehavior.java
7. Các tương tác để di chuyển mắt quan sát cảnh
Dùng chuột:
- Ví dụ dùng OrbitBehavior: hàm orbitControls, file InterpolatorDemo.java
Dùng bàn phím:
- Ví dụ dùng KeyNavigatorBehavior: file OrientedShape3Dapp.java
8. Tạo mô hình 3D của đối tượng
Dùng các primitive có sẵn:
- Từ Box, Cylinder, Sphere, Cone, kết hợp lại.
- Ví dụ StaticSceneExample.java
Trực tiếp gán hay tính tọa độ các đỉnh, chỉ số đỉnh các mặt tạo nên lưới đa giác của đối tượng:
- Gán giá trị:
Ví dụ:Tetrahedron.java, TestTetrahedron.java
- Tính giá trị từ phương trình:
Ví dụ: Torus.java, TestTorus.java
Load mô hình từ file ngoài Java.
9. Load mô hình 3D từ file ngoài
Kiểu file Java 3D hỗ trợ:
- *.obj; *.lwo
- import com.sun.j3d.loaders.*;
import com.sun.j3d.loaders.objectfile.*;
- dùng phương thức load của đối tượng ObjectFile. Ví dụ: hàm loadObjectFile trong InterpolatorDemo.java
Kiểu file Java 3D không trực tiếp hỗ trợ:
- *.3ds; *.wrt, *.cob.
- Add file porfolio.jar (trong gói NCSA Porfolio) vào project
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.*
- Dùng phương thức load của đối tuong75ModelLoader.
Ví dụ: hàm loadModelFromFile trong Load3Dmodel.java
10. Tạo Background của cảnh
Background của cảnh được hiển thị phía sau tất cả các đối tượng thấy của cảnh.
Hàm tạo:
Background() //màu đen
Background(Color3f color)
Background(ImageComponent2D image)
Ví dụ: Load3Dmodel.java
Background(BranchGroup geometry)
11. Chiếu sáng đối tượng 3D
Thành phần Geometry qui định hình thù và kích thước đối tượng.
Màu, texture, và các chi tiết apperance khác tạo nên bề mặt ngoài đối tượng. Đối tượng giống thế giới thực hay không chủ yếu ở thành phần này.
Trong thế giới thực, ảnh của vật qua cảm nhận của mắt người sẽ thay đổi theo ánh sáng bao quanh vật.
Trong Đồ họa máy tính, để ảnh của đối tượng 3D tiến gần đến “như thực”, cần tô màu từng điểm trên đối tượng theo một mô hình chiếu sáng nhất định.
Các kiểu ánh sáng:
Ánh sáng xung quanh (Ambient light):
- Ánh sáng yếu phản xạ ngẫu nhiên giữa các đối tượng
- Đồng nhất trong mọi vị trí và mọi hướng
- Như ánh sáng ban ngày nhưng mặt trời bị mây che
Ánh sáng có hướng (Directional light):
- Ánh sáng xuất phát từ nguồn sáng ở vô tận
- Tất cả tia sáng song song nhau
- Như ánh sáng của mặt trời
Ánh sáng điểm (Point light):
- Nguồn sáng tại một vị trí xác định và phát ra các tia sáng theo mọi hướng
- Như ánh sáng đèn hình cầu không chóa đèn
Ánh sáng pha (Spot light):
- Tương tự như ánh sáng điểm nhưng các tia sáng giới han trong hình nón
- Như ánh sáng của đèn pha
Các kiểu ánh sáng trong 3D
Các class ứng với kiểu ánh sáng:
Các hàm tạo:
- AmbientLight()
- AmbientLight(Color3f color)
- DirectionalLight()
- DirectionalLight(Color3f color, Vector3f direction)
- PointLight()
- PointLight(Color3f color, Point3f position, Point3f altenuation)
- SpotLight()
- SpotLight(Color3f color, Point3f position, Point3f altenuation, Vector3f direction, float speadAngle, float concentration)
Các kiểu ánh sáng trong 3D
Bật hay tắt ánh sáng:
- Void setEnable(boolean state)
Thiết lập phạm vi chiếu sáng của nguồn sáng
- Void setInfluencingBounds(Bound bounds)
- Các đối tượng ở ngoài phạm vi này sẽ không được tính toán chiếu sáng bởi nguồn sáng
12. Ánh xạ texture (Texture Mapping)
Là một phương thức “dán” các chi tiết nhỏ lên bề mặt đối tượng hình học từ một ảnh số có sẵn.
Một điểm trong ảnh Texture được gọi là một texel và một diểm trên bề mặt 3D được gọi là pixel.
Mỗi đỉnh trên bề mặt được gán cho một texel. Các pixel còn lại trên bề mặt sẽ được ánh xạ đến các texel thông qua nội suy.
TextureLoader loader = new TextureLoader(filename, this);
//Texture texture = loader.getTexture();
ImageComponent2D image = loader.getImage();
Texture2D texture = new Texture2D();
Texture.setImage(0, image);
Appearance appear = new Appearance();
Appear.setTexture(texture);
No comments:
Post a Comment