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

/* BG-->explSwitch-->explTG-->ImagesSeries
     |
     -->explPS PointSound

   Exploze je objekt typu ImagesSeries pod transformační skupinou
   a přepínacím ulzem. Uzel typu Switch se používá pro 
   zobrazení/skrití exploze a uzel typu TG pro pohyb a rotaci
   objektu typu ImagesSeries.

   Zvuk není připojen k uzlu explTG, protože způsobuje chybu,
   která se týká metodu processSwitchChanged() za běhu programu, 
   jakmile dojde k zapnutí zvuku. Místo toho se zvuk pohybuje
   samostatně prostřednictvím metody setPosition().
*/

import java.util.*;
import java.awt.*;
import javax.media.j3d.*;
import javax.vecmath.*;


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

  private BranchGroup explBG;
  private Switch explSwitch;
  private TransformGroup explTG;  
  private ImagesSeries explShape;
  private PointSound explPS;

  private Vector3d startVec, endVec;

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


  public ExplosionsClip(Vector3d svec, PointSound snd)
  {
    startVec = svec;
    explPS = snd;
    endVec = new Vector3d(0,0,0);   // počáteční hodnota

    explTG = new TransformGroup();
    explTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);  // bude se pohybovat
    explTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

    // umísti explozi na stejné místo jako střed paprsku
    explT3d.set(startVec);
    explTG.setTransform(explT3d);

    // exploze je objekt typu ImagesSeries, které nelze vybírat
    explShape = new ImagesSeries(2.0f, "images/explo", 6);
    explShape.setPickable(false);
    explTG.addChild( explShape );

    // vytvoř přepínač pro explozi
    explSwitch = new Switch();
    explSwitch.setCapability(Switch.ALLOW_SWITCH_WRITE);
    explSwitch.addChild( explTG );
    explSwitch.setWhichChild( Switch.CHILD_NONE );   // zpočátku je neviditelná

    // uzel typu TG, pod nímž vše visí
    explBG = new BranchGroup();
    explBG.addChild(explSwitch);
    explBG.addChild(explPS);
  } // konec metody: ExplosionsClip()


  public BranchGroup getExplBG()
  {  return explBG;  }



  public void showExplosion(double turnAngle, Point3d intercept)
  // otočí tak, aby směřovala k oku a ležela v místě kontaktu
  {
    endVec.set(intercept.x, intercept.y, intercept.z);
    rotateMove(turnAngle, endVec);  

    explSwitch.setWhichChild( Switch.CHILD_ALL );   // zviditelni
    explPS.setPosition((float)intercept.x, (float)intercept.y, (float)intercept.z);  
						// přesuň zvuk do cílového bodu
    explPS.setEnable(true);         // zapni zvuk exploze

    explShape.showSeries();         // zobraz explozi

    explPS.setEnable(false);        // vypnout zvuk
    explSwitch.setWhichChild( Switch.CHILD_NONE );   // zneviditelni

    // opět nasměruj vpřed a resetuj polohu
    rotateMove(-turnAngle, startVec); 
  }  // konec metody: showExplosion()



  private void rotateMove(double turn, Vector3d vec)
  // otoč explozi kolem osy y a přesuň na pozici dané vektorem vec
  {
    // System.out.println("turn: " + turn);
    explTG.getTransform(explT3d);       // získej transformační údaje exploze
	explT3d.setTranslation(ORIGIN);     // přesuň do počátku

    rotT3d.rotY(turn);      // otoč kolem osy y
    explT3d.mul(rotT3d);

	explT3d.setTranslation(vec);        // přesuň dle vektoru
    // System.out.println("End explT3d: " + explT3d);

    explTG.setTransform(explT3d);       // aktualizuj transformaci
  } // konec metody: rotateMove()


} // konec třídy: ExplosionsClip
