1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
void K3D_Leaf :: create(K3D_Branch* branch)
{
// On récupère la direction de la branche et (ses coordonnées)
Vecteur3D<float> branchDirection = branch->brForward;
Vecteur3D<float> branchLPosition = branch->brLCenter;
Vecteur3D<float> branchHPosition = branch->brHCenter;
float branchLRay = branch->brLRay;
float branchHRay = branch->brHRay;
// On place la feuille quelque part sur la branche (pas aux extrémités)
float coef = getRandom(0.2f,0.8f);
this->lePosition = branchLPosition*coef + branchHPosition*(1.0f-coef);
// On tient compte du cylindre
// Rayon du cylindre au point choisi
float branchLeafRay = branchLRay*coef + branchHRay*(1.0f-coef);
// Choix d'un angle de rotation / cylindre (il vaut zéro avec l'axe OX dans le plan XOY)
this->leAlpha = getRandom(-PI,PI);
// On en déduit précisemment la place de la feuille sur la branche (mm principe que pour la branche)
this->lePosition[0] += branchLeafRay*sin(this->leAlpha);
this->lePosition[2] += branchLeafRay*cos(this->leAlpha);
// Pour la direction, on suppose que la feuille a plus tendance à "descendre"
// On va combiner un vecteur aléatoire avec un vecteur -j
Vecteur3D<float> randomForward(getRandom(-1.0f,1.0f),getRandom(-1.0f,1.0f),getRandom(-1.0f,1.0f));
Vecteur3D<float> oppJ(0.0f,-1.0f,0.0f);
this->leForward = (randomForward + oppJ)*0.5f;
// Attention au signe de l'abscisse et la profondeur.
// si Alpha est entre -PI/2 et PI/2, x doit être positif sinon la feuille "rentre" dans la branche
// Idem avec z si alpha est entre 0 et PI
if (this->leAlpha > -PI/2 && this->leAlpha < +PI/2)
this->leForward[0] = Max(-this->leForward[0],this->leForward[0]);
else
this->leForward[0] = Min(-this->leForward[0],this->leForward[0]);
if (this->leAlpha > 0)
this->leForward[2] = Max(-this->leForward[2],this->leForward[2]);
else
this->leForward[2] = Min(-this->leForward[2],this->leForward[2]);
this->leForward.normalize();
// Maintenant, on s'occupe de l'autre direction
// Il est orthogonal à leForward mais sans composant y
// Attention au zéro !!
if (Max(this->leForward[0],-this->leForward[0]) > std::numeric_limits<float> :: epsilon())
this->leStraffing = Vecteur3D<float>(-this->leForward[2]/this->leForward[0],0.0f,1.0f);
else
{
if (this->leAlpha > 0 )
this->leStraffing = Vecteur3D<float>(0.0f,0.0f,1.0f);
else
this->leStraffing = Vecteur3D<float>(0.0f,0.0f,-1.0f);
}
this->leStraffing.normalize();
} |
Partager