예제 #1
0
void               P3DStemModelTube::ApplyAxisVariation
                                      (P3DMathRNG         *RNG,
                                       P3DStemModelTubeInstance
                                                          *Instance) const
 {
  float                                Angle1;
  float                                Angle2;
  float                                SinAngle1;
  float                                CosAngle1;
  P3DQuaternionf                       Q;
  unsigned int                         SegIndex;

  if (RNG == 0)
   {
    return;
   }

  for (SegIndex = 0; SegIndex < (AxisResolution - 1); SegIndex++)
   {
    Angle1 = RNG->UniformFloat(0,P3DMATH_PI * 2.0f);
    Angle2 = RNG->UniformFloat(-AxisVariation,AxisVariation) * P3DMATH_PI;

    P3DMath::SinCosf(&SinAngle1,&CosAngle1,Angle1);

    Q.FromAxisAndAngle(CosAngle1,0.0f,SinAngle1,Angle2);

    Instance->SetSegOrientation(SegIndex,Q.q);
   }
 }
예제 #2
0
void               P3DBranchingAlgBase::CalcBranchOrientationInCircleShape
                                      (P3DQuaternionf     *Orientation,
                                       float               X,
                                       float               Z,
                                       P3DMathRNG         *RNG) const
 {
  P3DQuaternionf   Rotation1Quat;
  P3DQuaternionf   Rotation2Quat;
  P3DQuaternionf   DeclinationQuat;
  P3DQuaternionf   TempQuat;
  float            DeclinationAngle;

  float XAxisVsPointAngle = P3DMath::ATan2(X,Z);

  Rotation1Quat.FromAxisAndAngle(0.0f,1.0f,0.0f,XAxisVsPointAngle);
  Rotation2Quat.FromAxisAndAngle(0.0f,1.0f,0.0f,Rotation);

  float SquaredRadius = Spread * Spread * 0.25f;
  float NormDistance;

  if (!P3DMATH_ALMOST_ZERO(SquaredRadius))
   {
    NormDistance = P3DMath::Sqrtf((X * X + Z * Z) / (Spread * Spread * 0.25f));
   }
  else
   {
    NormDistance = 0.0f;
   }

  if (RNG != 0)
   {
    NormDistance += RNG->UniformFloat(-DeclFactorV,DeclFactorV);
   }

  DeclinationAngle = P3DMath::Clampf
                      (-P3DMATH_PI * 0.5,P3DMATH_PI * 0.5,
                       NormDistance * DeclFactor * P3DMATH_PI * 0.5);

  DeclinationQuat.FromAxisAndAngle(1.0f,0.0f,0.0f,DeclinationAngle);

  P3DQuaternionf::CrossProduct(TempQuat.q,Rotation1Quat.q,DeclinationQuat.q);
  P3DQuaternionf::CrossProduct(Orientation->q,TempQuat.q,Rotation2Quat.q);
 }
예제 #3
0
void               P3DBranchingAlgStd::CreateBranches
                                      (P3DBranchingFactory          *Factory,
                                       const P3DStemModelInstance   *Parent,
                                       P3DMathRNG                   *RNG)
 {
  unsigned int                         BranchCount;
  float                                OffsetStep;
  float                                CurrRevAngle;
  float                                BranchRegionLength;

  CurrRevAngle = StartRevAngle;

  BranchRegionLength = Parent->GetLength() * (MaxOffset - MinOffset);

  if (BranchRegionLength <= 0.0f)
   {
    return;
   }

  if (RNG != 0)
   {
    BranchCount = (int)(BranchRegionLength * (Density + RNG->UniformFloat(-DensityV,DensityV) * Density));
   }
  else
   {
    BranchCount = (int)(BranchRegionLength * Density);
   }

  BranchCount /= Multiplicity;

  if (BranchCount < MinNumber)
   {
    BranchCount = MinNumber;
   }

  if (MaxLimitEnabled && BranchCount > MaxNumber)
   {
    BranchCount = MaxNumber;
   }

  if (BranchCount > 0)
   {
    P3DQuaternionf                     orientation;
    P3DQuaternionf                     decl;
    P3DQuaternionf                     rev;
    P3DQuaternionf                     Rot;
    P3DQuaternionf                     TempRot;
    float                              MultRevAngleStep;

    OffsetStep = (MaxOffset - MinOffset) / (BranchCount + 1);

    P3DVector3f CurrOffset(0.0f,MinOffset + OffsetStep,0.0f);

    MultRevAngleStep = (2.0f * P3DMATH_PI) / Multiplicity;

    for (unsigned int i = 0; i < BranchCount; i++)
     {
      float        BaseDeclination;

      for (unsigned int MultIndex = 0; MultIndex < Multiplicity; MultIndex++)
       {
        BaseDeclination = DeclinationCurve.GetValue(CurrOffset.Y());

        if (RNG != 0)
         {
          BaseDeclination += RNG->UniformFloat(-DeclinationV,DeclinationV) * BaseDeclination;
         }

        decl.FromAxisAndAngle(0.0f,0.0f,-1.0f,P3DMATH_DEG2RAD(180.0f * BaseDeclination));
        rev.FromAxisAndAngle(0.0f,1.0f,0.0f,CurrRevAngle + MultRevAngleStep * MultIndex);

        Rot.FromAxisAndAngle(0.0f,1.0f,0.0f,Rotation);

        P3DQuaternionf::CrossProduct(TempRot.q,rev.q,decl.q);
        P3DQuaternionf::CrossProduct(orientation.q,TempRot.q,Rot.q);

        Factory->GenerateBranch(&CurrOffset,&orientation);
       }

      if (RNG != 0)
       {
        CurrRevAngle += RevAngle + (RevAngle * RNG->UniformFloat(-RevAngleV,RevAngleV));
       }
      else
       {
        CurrRevAngle += RevAngle;
       }

      CurrOffset.Y() += OffsetStep;
     }
   }
 }
예제 #4
0
P3DStemModelInstance
                  *P3DStemModelTube::CreateInstance
                                      (P3DMathRNG         *rng,
                                       const P3DStemModelInstance
                                                          *parent,
                                       float               offset,
                                       const P3DQuaternionf
                                                          *orientation) const
 {
  P3DStemModelTubeInstance            *Instance;

  if (parent == 0)
   {
    float                              InstanceLength;

    InstanceLength = Length;

    if (rng != 0)
     {
      InstanceLength += rng->UniformFloat(-LengthV,LengthV) * InstanceLength;
     }

    if (orientation != 0)
     {
      P3DMatrix4x4f                    WorldTransform;

      orientation->ToMatrix(WorldTransform.m);

      Instance = new P3DStemModelTubeInstance
                      ( InstanceLength,
                        AxisResolution,
                        ProfileScaleBase,
                       &ProfileScaleCurve,
                        ProfileResolution,
                        UMode,
                        UScale,
                        VMode,
                        VScale,
                       &WorldTransform);
     }
    else
     {
      Instance = new P3DStemModelTubeInstance
                      ( InstanceLength,
                        AxisResolution,
                        ProfileScaleBase,
                       &ProfileScaleCurve,
                        ProfileResolution,
                        UMode,
                        UScale,
                        VMode,
                        VScale,
                        0);
     }
   }
  else
   {
    P3DMatrix4x4f                      ParentTransform;
    P3DMatrix4x4f                      WorldTransform;
    P3DQuaternionf                     ParentOrientation;
    P3DQuaternionf                     InstanceOrientation;
    P3DVector3f                        ParentAxisPos;
    P3DMatrix4x4f                      TempTransform;
    P3DMatrix4x4f                      TempTransform2;
    P3DMatrix4x4f                      TranslateTransform;
    float                              InstanceLength;

    parent->GetAxisOrientationAt(ParentOrientation.q,offset);
    parent->GetAxisPointAt(ParentAxisPos.v,offset);
    parent->GetWorldTransform(ParentTransform.m);

    P3DQuaternionf::CrossProduct(InstanceOrientation.q,
                                 ParentOrientation.q,
                                 orientation->q);

    InstanceOrientation.ToMatrix(TempTransform2.m);

    P3DMatrix4x4f::MakeTranslation(TranslateTransform.m,
                                   ParentAxisPos.X(),
                                   ParentAxisPos.Y(),
                                   ParentAxisPos.Z());
    P3DMatrix4x4f::MultMatrix(TempTransform.m,
                              TranslateTransform.m,
                              TempTransform2.m);

    P3DMatrix4x4f::MultMatrix(WorldTransform.m,
                              ParentTransform.m,
                              TempTransform.m);

    InstanceLength =
     parent->GetLength() * Length * LengthOffsetInfluenceCurve.GetValue(offset);

    if (rng != 0)
     {
      InstanceLength += rng->UniformFloat(-LengthV,LengthV) * InstanceLength;
     }

    Instance = new P3DStemModelTubeInstance
                    ( InstanceLength,
                      AxisResolution,
                      parent->GetMinRadiusAt(offset) * ProfileScaleBase,
                     &ProfileScaleCurve,
                      ProfileResolution,
                      UMode,
                      UScale,
                      VMode,
                      VScale,
                     &WorldTransform);
   }

  ApplyAxisVariation(rng,Instance);
  ApplyPhototropism(Instance);

  return(Instance);
 }
예제 #5
0
/*
 * CurrOrientation is in parent seg space
 * DestVector is in parent seg space
 */
static void        ApplyPhototropismToSegment
                                      (P3DQuaternionf       *NewOrientation,
                                       const float          *CurrOrientation,
                                       const float          *DestVector,
                                       float                 Factor)
 {
  // Find  branch direction after applying phototopism effect

  P3DVector3f SegmentY;

  SegmentY.Set(0.0f,1.0f,0.0);

  P3DQuaternionf::RotateVector(SegmentY.v,CurrOrientation);

  float CosA = P3DVector3f::ScalarProduct(DestVector,SegmentY.v);

  if (CosA >= 1.0f)
   {
    NewOrientation->Set(CurrOrientation);

    return; // nothing to do, SegmentY already points in DestVector direction
   }

  float Angle = P3DMath::ACosf(CosA);

  P3DVector3f Axis;

  if (Angle >= P3DMATH_PI)
   {
    Axis.Set(0.0f,0.0f,1.0f);
   }
  else
   {
    P3DVector3f::CrossProduct(Axis.v,SegmentY.v,DestVector);
    Axis.Normalize();
   }

  P3DQuaternionf Rotation;

  Rotation.FromAxisAndAngle(Axis.X(),Axis.Y(),Axis.Z(),Angle * Factor);

  P3DQuaternionf::RotateVector(SegmentY.v,Rotation.q);

  // Now find transformation from parent branch to SegmentY
  // CosA = P3DVector3f::ScalarProduct(SegmentY,(0,1,0));
  CosA = SegmentY.Y();

  if (CosA >= 1.0f)
   {
    NewOrientation->MakeIdentity();
   }
  else if (CosA <= -1.0f)
   {
    // P3Quaternion::FromAxisAndAngle((0,0,1),PI);
    NewOrientation->Set(0.0f,0.0f,1.0f,0.0f);
   }
  else
   {
    //Axis = P3DVector3f::CrossProduct(Axis.v,(0,1,0),SegmentY);

    Axis.Set(SegmentY.Z(),0.0f,-SegmentY.X());
    Axis.Normalize();

    NewOrientation->FromAxisAndAngle(Axis.X(),Axis.Y(),Axis.Z(),P3DMath::ACosf(CosA));
   }
 }
예제 #6
0
void               P3DCanvas3D::OnChar          (wxKeyEvent         &event)
 {
  bool             CameraChanged;
  int              KeyCode;

  CameraChanged = true;

  KeyCode = event.GetKeyCode();

  if (P3DApp::GetApp()->GetCameraControlPrefs()->EmulateNumpad)
   {
    if (event.CmdDown() && KeyCode >= '0' && KeyCode <= '9')
     {
      KeyCode = NumPadEmulationKeyMap[KeyCode - '0'];
     }
   }

  if      (KeyCode == WXK_NUMPAD1 || KeyCode == WXK_NUMPAD_END)
   {
    P3DQuaternionf           Rotation;

    camera.SetCenter(0.0f,0.0f,0.0f);

    if (event.ShiftDown())
     {
      Rotation.FromAxisAndAngle(0.0f,1.0f,0.0f,P3DMATH_PI);
      camera.SetDirection(Rotation.q[0],
                          Rotation.q[1],
                          Rotation.q[2],
                          Rotation.q[3]);
     }
    else
     {
      camera.SetDirection(0.0f,0.0f,0.0f,1.0f);
     }
   }
  else if (KeyCode == WXK_NUMPAD7 || KeyCode == WXK_NUMPAD_HOME)
   {
    P3DQuaternionf           Rotation;

    if (event.ShiftDown())
     {
      Rotation.FromAxisAndAngle(-1.0f,0.0f,0.0f,P3DMATH_PI / 2);
     }
    else
     {
      Rotation.FromAxisAndAngle(1.0f,0.0f,0.0f,P3DMATH_PI / 2);
     }

    camera.SetCenter(0.0f,0.0f,0.0f);
    camera.SetDirection(Rotation.q[0],
                        Rotation.q[1],
                        Rotation.q[2],
                        Rotation.q[3]);
   }
  else if (KeyCode == WXK_NUMPAD3 || KeyCode == WXK_NUMPAD_PAGEDOWN)
   {
    P3DQuaternionf           Rotation;

    if (event.ShiftDown())
     {
      Rotation.FromAxisAndAngle(0.0f,1.0f,0.0f,P3DMATH_PI / 2);
     }
    else
     {
      Rotation.FromAxisAndAngle(0.0f,-1.0f,0.0f,P3DMATH_PI / 2);
     }

    camera.SetCenter(0.0f,0.0f,0.0f);
    camera.SetDirection(Rotation.q[0],
                        Rotation.q[1],
                        Rotation.q[2],
                        Rotation.q[3]);
   }
  else if (KeyCode == WXK_NUMPAD4 || KeyCode == WXK_NUMPAD_LEFT)
   {
    camera.RotateWS(P3DMATH_PI / 12.0f,0.0f,1.0f,0.0f);
   }
  else if (KeyCode == WXK_NUMPAD6 || KeyCode == WXK_NUMPAD_RIGHT)
   {
    camera.RotateWS(P3DMATH_PI / 12.0f,0.0f,-1.0f,0.0f);
   }
  else if (KeyCode == WXK_NUMPAD8 || KeyCode == WXK_NUMPAD_UP)
   {
    camera.RotateCS(P3DMATH_PI / 12.0f,1.0f,0.0f,0.0f);
   }
  else if (KeyCode == WXK_NUMPAD2 || KeyCode == WXK_NUMPAD_DOWN)
   {
    camera.RotateCS(P3DMATH_PI / 12.0f,-1.0f,0.0f,0.0f);
   }
  else if (KeyCode == WXK_NUMPAD_ADD || KeyCode == '+' || KeyCode == '=')
   {
    ZoomFactor *= 0.75f;
   }
  else if (KeyCode == WXK_NUMPAD_SUBTRACT || KeyCode == '-')
   {
    ZoomFactor *= 4.0f / 3.0f;
   }
  else if (KeyCode == WXK_NUMPAD5 || KeyCode == WXK_NUMPAD_BEGIN)
   {
    OrthoCamera = !OrthoCamera;
   }
  else
   {
    CameraChanged = false;

    event.Skip();
   }

  if (CameraChanged)
   {
    P3DApp::GetApp()->InvalidateCamera();
    Refresh();
   }
 }