
// GunTurret.java
// Andrew Davison, April 2005, ad@fivedots.coe.psu.ac.th

/* Třída GunTurret realizuje válec s kuželovitou špicí, který
   se otáčí tak, aby ukazoval na místo na šachovnici vybrané uživatelem.

   uzel typu BG děla --> základní uzel typu TG --> válec
          |
          --> uzel typu TG  děla --> kužel

   Základní uzel typu TG se používá pouze pro počáteční umístění válce,
   takže leží na rovině XZ. Uzel typu TG děla má na starosti rotaci
   kužele.
*/

import javax.media.j3d.*;
import com.sun.j3d.utils.geometry.*;
import javax.vecmath.*;
import com.sun.j3d.utils.image.TextureLoader;


public class GunTurret
{
  private static final Vector3d ORIGIN = new Vector3d(0, 0, 0);

  private BranchGroup gunBG;
  private TransformGroup gunTG;
  private Vector3d startVec;

  // pro opakované výpočty
  private Transform3D gunT3d = new Transform3D();
  private Vector3d currTrans = new Vector3d();
  private Transform3D rotT3d = new Transform3D();


  public GunTurret(Vector3d svec)
  {
    startVec = svec;
    gunBG = new BranchGroup();
    Appearance apStone = stoneApp();
    placeGunBase(apStone);
    placeGun(apStone);
  } // konec metody: GunTurret()


  private Appearance stoneApp()
  // kamenný vzhled pomocí textury
  {
    Material stoneMat = new Material();  // standardně bílá
    stoneMat.setLightingEnable(true);

    Appearance apStone = new Appearance();
    apStone.setMaterial(stoneMat);

    TextureLoader stoneTex = new TextureLoader("images/stone.jpg", null);
    if (stoneTex != null) 
      apStone.setTexture(stoneTex.getTexture());

    // zkombinuj texturu s materiálem a osvětlením
    TextureAttributes texAttr = new TextureAttributes();
    texAttr.setTextureMode(TextureAttributes.MODULATE);
    apStone.setTextureAttributes(texAttr);

    return apStone;
  }  // konec metody: stoneApp()



  private void placeGunBase(Appearance apStone)
  // válec leží na rozivně XZ ve výšce 2 dílky
  {
    Transform3D baseT3d = new Transform3D();
    baseT3d.set( new Vector3d(0,1,0));   // take leží na rovině XZ
    TransformGroup baseTG = new TransformGroup();
    baseTG.setTransform(baseT3d);
    Cylinder cyl = new Cylinder(0.25f, 2.0f, Cylinder.GENERATE_NORMALS |
                              Cylinder.GENERATE_TEXTURE_COORDS, apStone);
    cyl.setPickable(false);  // základnu děla nelze vybírat
    baseTG.addChild( cyl );

    gunBG.addChild(baseTG);
  } // konec metody: placeGunBase()



  private void placeGun(Appearance apStone)
  // otočný kužel, jehož střed je 2 dílky na rovinou XZ
  {
    gunTG = new TransformGroup();
    gunTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);  // může rotovat
    gunTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

    gunT3d.set(startVec);   // vycentrován na vrcholek válce
    gunTG.setTransform(gunT3d);
    Cone cone = new Cone(1.0f, 2.0f, Cone.GENERATE_NORMALS |
                              Cone.GENERATE_TEXTURE_COORDS, apStone);
    cone.setPickable(false);   // kužel děla nelze vybírat
    gunTG.addChild(cone);

    gunBG.addChild(gunTG);
  }  // konec metody: placeGun()


  public BranchGroup getGunBG()
  {  return gunBG;  }



  public void makeRotation(AxisAngle4d rotAxis)
  // otoč kužel dělové věže
  {
    gunTG.getTransform( gunT3d );         // získej aktuální transformaci
    // System.out.println("Start gunT3d: " + gunT3d);
    gunT3d.get( currTrans );              // získej aktuální posun
	gunT3d.setTranslation( ORIGIN );      // posuň počátek

	rotT3d.setRotation( rotAxis );         // aplikuj rotaci
    gunT3d.mul(rotT3d);

	gunT3d.setTranslation( currTrans );   // přesuň zpět
    gunTG.setTransform( gunT3d );
    // System.out.println("End gunT3d: " + gunT3d);
  } // konec metody: makeRotation()


} // konec třídy: GunTurret
