[Fonctionne][Script] Une caméra pour objet embarqué

crea-coaster

Membre
8 Novembre 2009
592
52
26
Voilà je lance un topic à part du coup pour continuer à parler du script de camera embarquée.

EDIT: après résolution de problèmes, le script qui marche est celui-ci:

Code:
import com.nolimitscoaster.*;
import nlvm.math3d.*;

public class SiegeScript extends Script
{ 
  private SceneObject sco;
 private SceneObjectElement m_objet;
  
  private ExternalRideView seatView;
  private static final float warpPointRange = 3.0f;
  
  private Matrix4x4f extenderMatrix;
  private Vector3f initialExtenderVector;
  


 public bool onInit()
 {
  sco = sim.getSceneObjectForEntityId(getParentEntityId());
  if (sco == null) return false;
  
  seatView = sim.createExternalRideView();
  m_objet = sco.getElementForName("objet");
  
  return true;
 }
  
  
 public void onNextFrame(float tick)
 {
    
   Matrix4x4f mTrans = new Matrix4x4f();
    mTrans.initTrans(0.0f, 0.1f, 0.0f);
    
    Matrix4x4f mRotA = new Matrix4x4f();
    mRotA.initYRot((float)Math.PI * 0.0f);
    
      
   Matrix4x4f m = m_objet.getAbsoluteMatrix();
    m.multRight(mTrans);
    m.multRight(mRotA);
      
    seatView.setCameraMatrix(m);
    seatView.setEnterWarpPoint(m.getTrans(), warpPointRange);    
 }
  
  private Matrix4x4f InvertMatrix(Matrix4x4f m)
  {
    Matrix4x4f mi = new Matrix4x4f();
    mi.initIdentity();

    mi.setElemAt(0, 0, m.elemAt(0, 0));
    mi.setElemAt(1, 0, m.elemAt(0, 1));
    mi.setElemAt(2, 0, m.elemAt(0, 2));

    mi.setElemAt(0, 1, m.elemAt(1, 0));
    mi.setElemAt(1, 1, m.elemAt(1, 1));
    mi.setElemAt(2, 1, m.elemAt(1, 2));

    mi.setElemAt(0, 2, m.elemAt(2, 0));
    mi.setElemAt(1, 2, m.elemAt(2, 1));
    mi.setElemAt(2, 2, m.elemAt(2, 2));

    mi.setElemAt(3, 0, -m.elemAt(3, 0));
    mi.setElemAt(3, 1, -m.elemAt(3, 1));
    mi.setElemAt(3, 2, -m.elemAt(3, 2));

    return mi;
  }
  
}

Tu nomme l'objet (le .3ds, pas le .nl2sco) qui doit devenir une caméra "objet", et roule ma poule !

PS: Code qui peut poser problème avec un objet qui sort de Sketchup (sans que je sache pourquoi).
 
Ok, si celui ci fonctionne, édites le dans ton premier message. Ainsi on n'aura pas a chercher le bon dans les messages suivants...

Avec un cube nommé 'objet', ça tourne chez bibi ...

Code:
import com.nolimitscoaster.*;
import nlvm.math3d.*;

public class SiegeScript extends Script
{ 
  private SceneObject sco;
	private SceneObjectElement m_objet;
  
  private ExternalRideView seatView;
  private static final float warpPointRange = 3.0f;
  
  private Matrix4x4f extenderMatrix;
  private Vector3f initialExtenderVector;
  


	public bool onInit()
	{
  sco = sim.getSceneObjectForEntityId(getParentEntityId());
  if (sco == null) return false;
  
  seatView = sim.createExternalRideView();
  m_objet = sco.getElementForName("objet");
  
  return true;
	}
  
  
	public void onNextFrame(float tick)
	{
    
  	Matrix4x4f mTrans = new Matrix4x4f();
    mTrans.initTrans(0.0f, 0.1f, 0.0f);
    
    Matrix4x4f mRotA = new Matrix4x4f();
    mRotA.initYRot((float)Math.PI * 0.0f);
    
      
  	Matrix4x4f m = m_objet.getAbsoluteMatrix();
    m.multRight(mTrans);
    m.multRight(mRotA);
      
    seatView.setCameraMatrix(m);
    seatView.setEnterWarpPoint(m.getTrans(), warpPointRange);    
	}
  
  private Matrix4x4f InvertMatrix(Matrix4x4f m)
  {
    Matrix4x4f mi = new Matrix4x4f();
    mi.initIdentity();

    mi.setElemAt(0, 0, m.elemAt(0, 0));
    mi.setElemAt(1, 0, m.elemAt(0, 1));
    mi.setElemAt(2, 0, m.elemAt(0, 2));

    mi.setElemAt(0, 1, m.elemAt(1, 0));
    mi.setElemAt(1, 1, m.elemAt(1, 1));
    mi.setElemAt(2, 1, m.elemAt(1, 2));

    mi.setElemAt(0, 2, m.elemAt(2, 0));
    mi.setElemAt(1, 2, m.elemAt(2, 1));
    mi.setElemAt(2, 2, m.elemAt(2, 2));

    mi.setElemAt(3, 0, -m.elemAt(3, 0));
    mi.setElemAt(3, 1, -m.elemAt(3, 1));
    mi.setElemAt(3, 2, -m.elemAt(3, 2));

    return mi;
  }
  
}
 
Bon je suis désolé si ça devient un peu lourd, mais là ça tourne toujours pas.  :cry:
Tu pourrais me confirmer vite fait sur quel objet je met le script ? Quel objet je nomme "objet" ?  :-)
 
crea-coaster a dit:
Bon je suis désolé si ça devient un peu lourd, mais là ça tourne toujours pas.  :cry:
Tu pourrais me confirmer vite fait sur quel objet je met le script ? Quel objet je nomme "objet" ?  :-)
Vite c'est raté !  :wink:
N'importe quel objet ! Là j'ai pris un cube mais tu peut très bien nommer un siège...
 
Ok donc après test c'est donc un problème sur mon objet. En remplaçant le cube sur ta map par mon siège, erreur.
Donc me reste plus qu'à trouver où l'objet merde et c'est bon.  :mrgreen:
 
Bon j'ai toujours pas réussi à faire marcher le script sur mon siège, MAIS j'ai importé le cube sur ma map, parce que lui ça marche. Donc la caméra suit pas parfaitement le train, et se fait des fois rattraper par le siège (dit comme ça c'est bizarre, vous verrez sur la POV (sans doute dans la soirée)).

Je soupçonne mon problème de venir du fait que le siège sort de Sketchup, donc éviter d'appliquer le script sur un objet qui sort de Sketchup, sauf bien sur si on sait pourquoi ça marche pas.  :-D
Bref je considère que le script marche, donc je l'affiche dans mon premier message.


Merci pour tout Yoyo  :mrgreen:
 
Essayes alors celui-ci ...

Code:
import com.nolimitscoaster.*;
import nlvm.math3d.*;

public class SiegeScript extends Script
{
	private SceneObject _sco;
	private SceneObjectElement _seat02;
	private Vector3f _seat02_Axis ;
  
	private static final String scriptName = "Freesbie";

  
 	private static final float c_warpRange = 15.0f;
  
  private ExternalRideView view;
	private Matrix4x4f viewCamera = new Matrix4x4f();	
	private float viewX = 0;
	private float viewZ = 0;
	private Vector3f posOut = new Vector3f(0,0,0);	
	private Vector3f pitchHeadBankOut = new Vector3f(0,1,0);
	private float seatOffsetVertical = 0.0f;
	private float seatOffsetHorizontal = 0.0f;
	private float seatOffsetRotation = 0.0f;	
  
  
  
  public bool onInit()
  {
    _sco = sim.getSceneObjectForEntityId(getParentEntityId());
    
	  _seat02 = _sco.getElementForName("objet");
     if (_seat02 == null) 
    {
      System.err.println(scriptName + ": element not found: _seat02");
      return false;
    }  

	  _seat02_Axis = new Vector3f(0, 0.02f, 0);
	  
		view = sim.createExternalRideView();
		view.setCurrentCarIndex(1);
		view.setEnterWarpPoint(_sco.getTranslation(), c_warpRange);
		view.setLabel("Tornado");
	
    
    return true;
  }

  
  public void onNextFrame(float tick)
  {	
  	_seat02.setTranslation(_seat02_Axis);
  	
    
  
	
	
		//view.setEnterWarpPointEnabled(bWPEnable);
    
    if (view.isActive())
    { 
      viewCamera = _seat02.getAbsoluteMatrix();	
		Tools.matrixToPitchHeadBankPos(viewCamera, pitchHeadBankOut, posOut);
	
		viewZ = (float)Math.cos(pitchHeadBankOut.y + seatOffsetRotation) * seatOffsetHorizontal;
		viewX = (float)Math.sin(pitchHeadBankOut.y + seatOffsetRotation) * seatOffsetHorizontal;
				
		viewCamera.setElemAt(3,0,(viewCamera.elemAt(3,0) + viewX));		// X		
		viewCamera.setElemAt(3,1,(viewCamera.elemAt(3,1) + seatOffsetVertical));	// Y
		viewCamera.setElemAt(3,2,(viewCamera.elemAt(3,2) + viewZ));	// Z
		view.setCameraMatrix(viewCamera);
	  }
	
	
	}
}


     
 
Nan mais c'est pas grave Yoyo arrête de te creuser la tête c'est la faute à mon objet, qui n'est pas reconnu par le script, puisque celui-ci m'indique "element not found: _seat2". Donc c'est nolimit qui a un soucis avec les objets Sketchup, et je vais m’atteler dès maintenant à trouver quoi.  :mort:

Merci encore pour l'aide.  :-)
 
En principe, un objet porte un nom de fichier et un nom d'objet.
Code:
_seat02 = _sco.getElementForName("objet");

_sco est le fichier alors que 'ElementForName' est l'intitulé de l'objet.

Un fichier peu comporter une multitude d'objets, c'est pourquoi il faut déterminer lequel on veut activer.
Tu dois avoir un endroit dans ketchup où tu nommes chaque pièce de ton objet, c'est celui ci...

EDIT : Si il n'y a pas besoin de définir une 'pièce', _sco suffit.

Pour le script, il te faut savoir que la camera un fois scriptée à l'objet se place au point de pivot de l'objet.
Idem si après tu mets l'objet en 'objet embarqué'.
Tu as un car0 sur ton train ? Le script d'objet embarqué se règle et si tu n'es pas juste, tu va avoir du décalage. Si tu a ton objet sur le car1, il te faut modifier la ligne :
Code:
private static final int carToAttach = 0; // Defini le wagon (0 = zero car)

 
j'y ai passé un moment et effectivement, il y a un offset, le même qu'il y a en mode onride.
Faudrait re-demonter le script tango.nlvm et n'en garder que la vue caméra car sur le tango, la vue suit parfaitement les sièges.
Sorry pour la prise de tête mais je commence a me dire que ça fait parti du jeu.