GeometryInfo を使って、三角形ポリゴンを組み合わせて四面体を描画します。
またアルファチャネル(透明度)を設定した色を使います。
赤が完全に透明に、緑が不透明に、青と黄は背景画像が透けて見えます。

前田稔の超初心者のプログラム入門

プログラムの作成

  1. GeometryInfo を使って、三角形ポリゴンを組み合わせて四面体を描画します。
    メモ帳などでタイプして Men4Normal.java の名前で保存して下さい。
    //★ GeometryInfo で四面体を生成する    前田 稔
    import java.awt.*;
    import javax.swing.*;
    import javax.media.j3d.*;
    import javax.vecmath.*;
    import com.sun.j3d.utils.universe.*;
    import com.sun.j3d.utils.behaviors.mouse.*;
    import com.sun.j3d.utils.geometry.*;
    
    // Main Class
    public class Men4Normal extends JFrame
    {
        // main Method
        public static void main(String[] args)
        {   new Men4Normal();  }
    
        // Constructor
        public Men4Normal()
        {   // JFrame の初期化
            super("4 Mentai");
            setSize(300,300);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // Java3D関係の設定
            GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration();
            Canvas3D canvas = new Canvas3D(g_config);
            add(canvas);
    
            // SimpleUniverseを生成
            SimpleUniverse universe = new SimpleUniverse(canvas);
            universe.getViewingPlatform().setNominalViewingTransform();
    
            // シーンの生成
            universe.addBranchGraph(CreateScene());
            setVisible(true);
        }
    
        //  三角ポリゴンで四面体を生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
    
            // 四面体の頂点座標を定義
            Point3d[] vertices =
            {  new Point3d(0.0, 0.0, -0.4), new Point3d(0.0, 0.8, 0.2),  new Point3d(0.5, 0.0, 0.5),
               new Point3d(0.0, 0.0, -0.4), new Point3d(-0.5, 0.0, 0.5), new Point3d(0.0, 0.8, 0.2),
               new Point3d(0.0, 0.0, -0.4), new Point3d(0.5, 0.0, 0.5),  new Point3d(-0.5, 0.0, 0.5),
               new Point3d(0.5, 0.0,  0.5), new Point3d(0.0, 0.8, 0.2),  new Point3d(-0.5, 0.0, 0.5)
            };
    
            // 平行光源の設定
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
            DirectionalLight dlight =
                new DirectionalLight(true, new Color3f(1.0f,1.0f,1.0f), new Vector3f(0.3f,-0.3f,-0.3f));
            dlight.setInfluencingBounds(bounds);
            objRoot.addChild(dlight);
    
            // 環境光の設定
            AmbientLight alight = new AmbientLight();
            alight.setInfluencingBounds(bounds);
            objRoot.addChild(alight);
    
            // Mouse 操作の設定
            TransformGroup trans = new TransformGroup();
            SetMouse(objRoot, trans);
    
            // 四面体を作成
            GeometryInfo ginfo = new GeometryInfo(GeometryInfo.TRIANGLE_ARRAY);
            ginfo.setCoordinates(vertices);
    
            // 法線ベクトルの設定
            NormalGenerator gen = new NormalGenerator();
            gen.generateNormals(ginfo);
    
            // Material を設定して BranchGroup に追加
            Shape3D shape = new Shape3D(ginfo.getGeometryArray());
            shape.setAppearance(createAppearance());
    
            // BranchGroup に登録
            trans.addChild(shape);
            objRoot.addChild(trans);
            return objRoot;
        }
    
        // Material の設定
        private Appearance createAppearance()
        {   Material mat = new Material();
            // デフォルト値
            mat.setLightingEnable(true);            // 照明が有効
            mat.setAmbientColor(0.2f, 0.2f, 0.2f);  // 環境光による色は   濃いグレー
            mat.setEmissiveColor(0.0f, 0.0f, 0.0f); // 発光による色は     黒(発光しない)
            mat.setDiffuseColor(1.0f, 1.0f, 1.0f);  // 拡散反射による色は 白
            mat.setSpecularColor(1.0f, 1.0f, 1.0f); // 鏡面反射による色は 白
            mat.setShininess(64.0f);                // 輝度は             64(中間値)
    
            mat.setDiffuseColor(new Color3f(0.8f, 0.8f, 0.0f));
            Appearance ap = new Appearance();
            ap.setMaterial(mat);
            return ap;
        }
    
        // Mouse 操作の設定
        public void SetMouse(BranchGroup objRoot, TransformGroup trans)
        {
            // Model の修正を許可
            trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
            trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    
            // 回転を設定
            BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);
            MouseRotate rotator = new MouseRotate(trans);
            rotator.setSchedulingBounds(bounds);
            objRoot.addChild(rotator);
    
            // 移動を設定
            MouseTranslate translator = new MouseTranslate(trans);
            translator.setSchedulingBounds(bounds);
            objRoot.addChild(translator);
    
            // ズームを設定
            MouseZoom zoomer = new MouseZoom(trans);
            zoomer.setSchedulingBounds(bounds);
            objRoot.addChild(zoomer);
        }
    }
    

説明

  1. モデルを立体的に見せるには、ライトで照らして「光と影」を演出しなければなりません。
    物体は光を反射してその姿が見えるのですが、強く光を反射する方向を法線ベクトルで設定します。
    GeometryInfo を使うと簡単に法線ベクトルを設定することが出来ます。
    GeometryInfo は GeometryArray を引数にして生成出来るのですが、ここでは primitive で直接生成する方法を説明します。
    法線ベクトルの説明は 前田稔の超初心者のプログラム入門 から「DirectX9/マテリアルを設定して、虎のモデルを描画する」を参照して下さい。
  2. Point3d[] で四面体の頂点座標を定義します。
    DirectionalLight() で平行光源を設定します。
    光源には「環境光/平行光源/点光源/スポットライト」があります。
    new BoundingSphere(new Point3d(),100.0); で光源が作用する範囲を設定します。
    Color3f(1.0f,1.0f,1.0f) は光源の色(白)で、Vector3f(0.3f,-0.3f,-0.3f) は光源の向きです。
    向きは 0.3f:やや右方向を、-0.3f:やや下向きに、-0.3f:やや奥方向を照らします。
    ちなみに Vector3f(0.0f, 0.0f, -1.0f) で正面から、new Vector3f(0.87f, 0.0f, -0.5f) で斜め左方向から照明があたります。
    AmbientLight() は環境光の設定で、Light に照らされない部分を薄暗くします。
    四面体をマウスで操作する方法は前と同じです。
        // 三角ポリゴンで四面体を生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
    
            // 四面体の頂点座標を定義
            Point3d[] vertices =
            {  new Point3d(0.0, 0.0, -0.4), new Point3d(0.0, 0.8, 0.2),  new Point3d(0.5, 0.0, 0.5),
               new Point3d(0.0, 0.0, -0.4), new Point3d(-0.5, 0.0, 0.5), new Point3d(0.0, 0.8, 0.2),
               new Point3d(0.0, 0.0, -0.4), new Point3d(0.5, 0.0, 0.5),  new Point3d(-0.5, 0.0, 0.5),
               new Point3d(0.5, 0.0,  0.5), new Point3d(0.0, 0.8, 0.2),  new Point3d(-0.5, 0.0, 0.5)
            };
    
            // 平行光源の設定
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
            DirectionalLight dlight =
                new DirectionalLight(true, new Color3f(1.0f,1.0f,1.0f), new Vector3f(0.3f,-0.3f,-0.3f));
            dlight.setInfluencingBounds(bounds);
            objRoot.addChild(dlight);
    
            // 環境光の設定
            AmbientLight alight = new AmbientLight();
            alight.setInfluencingBounds(bounds);
            objRoot.addChild(alight);
    
            // Mouse 操作の設定
            TransformGroup trans = new TransformGroup();
            SetMouse(objRoot, trans);
        
  3. new GeometryInfo(GeometryInfo.TRIANGLE_ARRAY) で、四面体を生成します。
            // 四面体を作成
            GeometryInfo ginfo = new GeometryInfo(GeometryInfo.TRIANGLE_ARRAY);
            ginfo.setCoordinates(vertices);
        
  4. NormalGenerator を生成して generateNormals(ginfo); で法線ベクトルを設定します。
    法線ベクトルを設定する最も簡単な方法です。
            // 法線ベクトルの設定
            NormalGenerator gen = new NormalGenerator();
            gen.generateNormals(ginfo);
        
  5. new Shape3D(ginfo.getGeometryArray()); で GeometryInfo を引数にして Shape3D を生成します。
    shape.setAppearance(createAppearance()) で、マテリアルを設定した Appearance を生成します。
    TransformGroup に Shape3D を追加します。
    BranchGroup に TransformGroup を追加します。
            // Material を設定して BranchGroup に追加
            Shape3D shape = new Shape3D(ginfo.getGeometryArray());
            shape.setAppearance(createAppearance());
    
            // BranchGroup に登録
            trans.addChild(shape);
            objRoot.addChild(trans);
            return objRoot;
        }
        
  6. Appearance を生成する createAppearance() メソッドです。
    モデルに色や光沢など Material を設定します。
    マテリアルの説明は 前田稔の超初心者のプログラム入門 から「DirectX9/球をライトで照らして View 座標を回転する」を参照して下さい。
    setDiffuseColor() がモデルの色で、赤・緑・青の順に 0.0〜1.0 の範囲で設定します。
    モデルの色を変えて試してみて下さい。
        // Material の設定
        private Appearance createAppearance()
        {   Material mat = new Material();
            // デフォルト値
            mat.setLightingEnable(true);            // 照明が有効
            mat.setAmbientColor(0.2f, 0.2f, 0.2f);  // 環境光による色は   濃いグレー
            mat.setEmissiveColor(0.0f, 0.0f, 0.0f); // 発光による色は     黒(発光しない)
            mat.setDiffuseColor(1.0f, 1.0f, 1.0f);  // 拡散反射による色は 白
            mat.setSpecularColor(1.0f, 1.0f, 1.0f); // 鏡面反射による色は 白
            mat.setShininess(64.0f);                // 輝度は             64(中間値)
    
            mat.setDiffuseColor(new Color3f(0.8f, 0.8f, 0.0f));
            Appearance ap = new Appearance();
            ap.setMaterial(mat);
            return ap;
        }
        
  7. Mouse の操作を設定する SetMouse() メソッドです。
    マウスの左ボタンを押しながらドラッグするとモデルが回転します。
    マウスの右ボタンを押しながらドラッグするとモデルが移動します。
    マウスの中央ボタンを押しながらドラッグするとモデルがズームイン・ズームアウトします。
        // Mouse 操作の設定
        public void SetMouse(BranchGroup objRoot, TransformGroup trans)
        {
            // Model の修正を許可
            trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
            trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    
            // 回転を設定
            BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);
            MouseRotate rotator = new MouseRotate(trans);
            rotator.setSchedulingBounds(bounds);
            objRoot.addChild(rotator);
    
            // 移動を設定
            MouseTranslate translator = new MouseTranslate(trans);
            translator.setSchedulingBounds(bounds);
            objRoot.addChild(translator);
    
            // ズームを設定
            MouseZoom zoomer = new MouseZoom(trans);
            zoomer.setSchedulingBounds(bounds);
            objRoot.addChild(zoomer);
        }
        

Alpha チャネルを使う

  1. 四面体にアルファチャネル(透明度)を設定した色を使います。
    色の定義には R(赤),G(緑),B(青) 以外に W や A などで表わされるアルファチャネル(透明度)があります。
    アルファチャネルの説明は 前田稔の超初心者のプログラム入門 から「DirectX9/超初心者のための入門/DDS 形式の画像ファイルを作成する」を参照して下さい。
    //★ 四面体にアルファチャネルを設定した色を使う    前田 稔
    import java.awt.*;
    import javax.swing.*;
    import java.io.*;
    import javax.imageio.ImageIO;
    import java.awt.image.BufferedImage;
    import javax.media.j3d.*;
    import javax.vecmath.*;
    import com.sun.j3d.utils.universe.*;
    import com.sun.j3d.utils.behaviors.mouse.*;
    import com.sun.j3d.utils.geometry.*;
    
    // Main Class
    public class Men4ColorAlpha extends JFrame
    {
        // main Method
        public static void main(String[] args)
        {   new Men4ColorAlpha();  }
    
        // Constructor
        public Men4ColorAlpha()
        {   // JFrame の初期化
            super("4 Mentai");
            setSize(300,300);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            // Java3D関係の設定
            GraphicsConfiguration g_config = SimpleUniverse.getPreferredConfiguration();
            Canvas3D canvas = new Canvas3D(g_config);
            add(canvas);
    
            // SimpleUniverseを生成
            SimpleUniverse universe = new SimpleUniverse(canvas);
            universe.getViewingPlatform().setNominalViewingTransform();
    
            // シーンの生成
            universe.addBranchGraph(CreateScene());
            setVisible(true);
        }
    
        // 三角ポリゴンで四面体を生成
        private BranchGroup CreateScene()
        {   BranchGroup objRoot = new BranchGroup();
    
            // 四面体の座標を定義
            Point3d[] vertices =
            {  new Point3d(0.0, 0.0, -0.4), new Point3d(0.0, 0.8, 0.2),  new Point3d(0.5, 0.0, 0.5),
               new Point3d(0.0, 0.0, -0.4), new Point3d(-0.5, 0.0, 0.5), new Point3d(0.0, 0.8, 0.2),
               new Point3d(0.0, 0.0, -0.4), new Point3d(0.5, 0.0, 0.5),  new Point3d(-0.5, 0.0, 0.5),
               new Point3d(0.5, 0.0,  0.5), new Point3d(0.0, 0.8, 0.2),  new Point3d(-0.5, 0.0, 0.5)
            };
    
            // ポリゴンの頂点座標の色を定義
            Color4f[] colors =
            {  new Color4f(1.0f,0.0f,0.0f,0.0f), new Color4f(1.0f,0.0f,0.0f,0.0f), new Color4f(1.0f,0.0f,0.0f,0.0f),   // red(透明)
               new Color4f(0.0f,1.0f,0.0f,1.0f), new Color4f(0.0f,1.0f,0.0f,1.0f), new Color4f(0.0f,1.0f,0.0f,1.0f),   // green(不透明)
               new Color4f(0.0f,0.0f,1.0f,0.3f), new Color4f(0.0f,0.0f,1.0f,0.3f), new Color4f(0.0f,0.0f,1.0f,0.3f),   // blue
               new Color4f(1.0f,1.0f,0.0f,0.7f), new Color4f(1.0f,1.0f,0.0f,0.7f), new Color4f(1.0f,1.0f,0.0f,0.7f) }; // yellow
    
            // 平行光源の設定
            BoundingSphere bounds = new BoundingSphere(new Point3d(),100.0);
            DirectionalLight dlight =
                new DirectionalLight(true, new Color3f(1.0f,1.0f,1.0f), new Vector3f(0.3f,-0.3f,-0.3f));
            dlight.setInfluencingBounds(bounds);
            objRoot.addChild(dlight);
    
            // 環境光の設定
            AmbientLight alight = new AmbientLight();
            alight.setInfluencingBounds(bounds);
            objRoot.addChild(alight);
    
            // Mouse 操作の設定
            TransformGroup trans = new TransformGroup();
            SetMouse(objRoot, trans);
    
            // 四面体を作成
            GeometryInfo ginfo = new GeometryInfo(GeometryInfo.TRIANGLE_ARRAY);
            ginfo.setCoordinates(vertices);
            ginfo.setColors(colors);
    
            // 法線ベクトルの設定
            NormalGenerator gen = new NormalGenerator();
            gen.generateNormals(ginfo);
    
            // Material を設定して BranchGroup に追加
            Shape3D shape = new Shape3D(ginfo.getGeometryArray());
            shape.setAppearance(createAppearance());
    
            // BranchGroup に登録
            trans.addChild(shape);
            objRoot.addChild(trans);
    
            // 背景画像の設定
            BufferedImage image = loadImage("C:\\DATA\\Test\\back.jpg");
            //BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 10000.0);
            Background bg = new Background();
            bg.setApplicationBounds(bounds);
            bg.setCapability(Background.ALLOW_IMAGE_WRITE);
            bg.setImage(new ImageComponent2D(ImageComponent.FORMAT_RGB, image));
            objRoot.addChild(bg);
            return objRoot;
        }
    
        // Material の設定
        private Appearance createAppearance()
        {   Material mat = new Material();
            mat.setDiffuseColor(new Color3f(0.8f, 0.8f, 0.0f));
            Appearance ap = new Appearance();
            ap.setMaterial(mat);
    
            //※ 透明度の設定
            ap.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.0f));
            return ap;
        }
    
        // Mouse 操作の設定
        public void SetMouse(BranchGroup objRoot, TransformGroup trans)
        {
            // Model の修正を許可
            trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
            trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    
            // 回転を設定
            BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);
            MouseRotate rotator = new MouseRotate(trans);
            rotator.setSchedulingBounds(bounds);
            objRoot.addChild(rotator);
    
            // 移動を設定
            MouseTranslate translator = new MouseTranslate(trans);
            translator.setSchedulingBounds(bounds);
            objRoot.addChild(translator);
    
            // ズームを設定
            MouseZoom zoomer = new MouseZoom(trans);
            zoomer.setSchedulingBounds(bounds);
            objRoot.addChild(zoomer);
        }
    
        // BufferedImage の入力
        public static BufferedImage loadImage(String fileName)
        {   InputStream is = null;
            try
            {   is = new FileInputStream(fileName);
                BufferedImage img = ImageIO.read(is);
                return img;
            }
            catch (IOException e)
            {   throw new RuntimeException(e);  }
            finally
            {   if (is != null)
                    try { is.close(); }
                    catch (IOException e) {}
            }
        }
    }
    
  2. 四面体に設定するアルファチャネル(透明度)を付加した色 Color4f[] を定義します。
    RGB に続く4つ目がアルファチャネルで 1.0f が不透明で 0.0f で完全に透明になります。
    red を透明に、green を不透明に、blue を 0.3f に、yellow を 0.7f に設定しています。
            // ポリゴンの頂点座標の色を定義
            Color4f[] colors =
            {  new Color4f(1.0f,0.0f,0.0f,0.0f), new Color4f(1.0f,0.0f,0.0f,0.0f), new Color4f(1.0f,0.0f,0.0f,0.0f),   // red(透明)
               new Color4f(0.0f,1.0f,0.0f,1.0f), new Color4f(0.0f,1.0f,0.0f,1.0f), new Color4f(0.0f,1.0f,0.0f,1.0f),   // green(不透明)
               new Color4f(0.0f,0.0f,1.0f,0.3f), new Color4f(0.0f,0.0f,1.0f,0.3f), new Color4f(0.0f,0.0f,1.0f,0.3f),   // blue
               new Color4f(1.0f,1.0f,0.0f,0.7f), new Color4f(1.0f,1.0f,0.0f,0.7f), new Color4f(1.0f,1.0f,0.0f,0.7f) }; // yellow
        
  3. GeometryInfo で四面体を生成するのですが、ginfo.setColors(colors); で色を設定しています。
            // 四面体を作成
            GeometryInfo ginfo = new GeometryInfo(GeometryInfo.TRIANGLE_ARRAY);
            ginfo.setCoordinates(vertices);
            ginfo.setColors(colors);
        
  4. 透明度が良く解るように背景画像を描画しました。
    "C:\\DATA\\Test\\back.jpg" が背景画像です。
            // 背景画像の設定
            BufferedImage image = loadImage("C:\\DATA\\Test\\back.jpg");
            //BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 10000.0);
            Background bg = new Background();
            bg.setApplicationBounds(bounds);
            bg.setCapability(Background.ALLOW_IMAGE_WRITE);
            bg.setImage(new ImageComponent2D(ImageComponent.FORMAT_RGB, image));
            objRoot.addChild(bg);
        
  5. createAppearance() メソッドで setTransparencyAttributes() を設定して下さい。
    これでアルファチャネルが有効になります。
        // Material の設定
        private Appearance createAppearance()
        {   Material mat = new Material();
            mat.setDiffuseColor(new Color3f(0.8f, 0.8f, 0.0f));
            Appearance ap = new Appearance();
            ap.setMaterial(mat);
    
            //※ 透明度の設定
            ap.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.BLENDED, 0.0f));
            return ap;
        }
        
  6. マウス操作で回転すると、赤が完全に透明になって背景画像が透けて見えます。
    また青と黄は、背景画像と重なって見えるでしょう。
    setTransparencyAttributes() をコメントアウトすると、透明度が効かなくなるので試して下さい。

超初心者のプログラム入門(Java2)