Menu

Using GL Actor (moves very slowly)

Help
Sergio
2017-06-04
2017-06-06
  • Sergio

    Sergio - 2017-06-04

    I am starting to use, by the first time the TGLactor components. I used most of the samples and they work well and the actors move wald or run with a "normal "speed.
    Then I took the component and configurations in the sample Skeletal exactly ( I hope) as they are in the sample to my code. In my code have several components (see attached figure). When I put the actor to walk it moves in a extremely low speed ( FPS ~0 )
    Question 1) Is this caused by a worng configuration in my code or because there are many components. I am noting that when I save the code it is saving slowlyas whwn we have a big code (it is not the case). Below i copies the relevant part ofthe code (it is big to put everything)

    IN THE FORMCREATE EVENT
    pathMainDir:=ExtractFilePath(Application.ExeName);
    // SetGLSceneMediaDir(); ver post do Jerome 3/6/2017
    SetCurrentDir( pathMainDir+'\Media') ;
    Actor1.LoadFromFile('trinityRage.smd');
    // Load the walk & run animations and "fix" their translation
    // (HL walk/run animations have a built-in "slide" that we don't want here)
    Actor1.AddDataFromFile('walk.smd');
    Actor1.Animations[1].MakeSkeletalTranslationStatic;
    Actor1.AddDataFromFile('run.smd');
    Actor1.Animations[2].MakeSkeletalTranslationStatic;
    // Then load the two jumps
    Actor1.AddDataFromFile('long_jump.smd');
    Actor1.AddDataFromFile('jump.smd');
    // And the 'look_left_right' blending animations, that we immediately
    // assign to the controler. The MakeSkeletalRotationDelta removes absolute
    // information from the SMD (which HL may use, but GLScene doesn't)
    Actor1.AddDataFromFile('look_left_right.smd');

    Actor1.Animations[5].MakeSkeletalRotationDelta;
    AnimationControler1.AnimationName:='look_left_right';
    // Skeleton visible, and start with walk animation
    // (pseudo-animation 0 is for the static model in its default attitude)
    Actor1.OverlaySkeleton:=True;
    baseAnimation:='walk';
    Actor1.SwitchToAnimation(baseAnimation);

    CBSkeletonClick(self); //skeletor
    Actor1.Scale.SetVector(0.04, 0.04, 0.04, 0);
    Actor1.Position.SetPoint(20, 1, 10);
    AnimateSFCClick(self);
    Show;
    end;

    IN THE BUTTON TO START ANIMATION
    if AnimateSFC.ItemIndex=2 then
    begin
    timer1.Enabled:=true;
    Running:= true;
    Actor1.AnimationMode := aamLoop;
    with GLcadencer1 do
    begin
    Enabled:=true;
    MaxDeltaTime :=0.01;
    Mode:=cmASAP;
    timeMultiplier:= time_multiplier; //
    timeReference:= cmPerformanceCounter;
    end;
    VIEW.ResetPerformanceMonitor;

    THE OTHER PARTS ARE EQUAL TO THE SAMPLE SKELETAL
    
     
  • Sergio

    Sergio - 2017-06-04

    The attachment

    QUESTION 2) Whwn I close the screen I am getting an error in GLwin32Viewer uit (access violation)

    function TGLSceneViewer.FramesPerSecond: Single;
    begin
    Result := FBuffer.FramesPerSecond;
    end;

    QUESTION 3)
    Where can I find some other types of actor models different from the ones in the samples ? For example a worker with a hat in the head
    Thanks in advance

     
  • Sergio

    Sergio - 2017-06-06

    I tried in another computer and it is also very slow but slightly better. Is there anything I can try to do ?
    Please help me

     
  • Jerome.D (BeanzMaster)

    I Sergio first what the FPS without Actor ?
    How do you manage and handle actor moves ?

     
  • Sergio

    Sergio - 2017-06-09

    Thanks Jerome I am mounting all the components again to check if there is any "hidden" prblem causing the almost zero FPS when I put the actor inside my code (although runs very well in the sample code).I will wrirte again after posting the code

     
  • Jerome.D (BeanzMaster)

    Ok but tell me FPS without Actor, please and how many objects/Faces you display.
    Perhaps, for having better performances, you can try Object Sorting property. If you have duplicated object try to play with ProxyObject
    How is the structure of your scene

    it is something like this ?

    • Root
      • UserInterface
      • World
        • GlobalLights
          • Light1
          • Light2
        • WorldCameras
          • Camera
        • House
          • Room 1
            • RoomLights
              • Light1
          • Walls
          • Technicals
            • ElectricWire1
            • ElectricWire2
        • Player
          • Actor
     

    Last edit: Jerome.D (BeanzMaster) 2017-06-09
  • Sergio

    Sergio - 2017-06-09

    Hi Jerome The structure is the one you may see in the attachment. Some 30 other 30 components are created in runtime but nothing special (cibes, cylinders, ellisoids) .
    Unfortunately the other procedure that generate the positions and coordinates of the components used in the scene is so big and confusing that I cannot separate both and post here.
    I went to measure the FPS without actor and I noticed that there is something strange with my current version of the code. Another animation , without actor, which works well for a long time is also more slow than before.
    So decided to re-make my code putting the actor and all the components in a copy of the (very good) GLSviewer sample. When it is ready, in few days, I will post and comment here.what happened .
    Thanks again for the help

     
  • Sergio

    Sergio - 2017-06-09

    Low here means without actor FPS around 3 with code below creating some spheres

    procedure TF_3DD.GLCadencer1Progress(Sender: TObject; const deltaTime, newTime: Double);
    var velocitySphere:single;
    begin
    if ((running=true) and (countSpheres < NmaxSpheres)) then
    begin
    StaticText1.Caption:=IntToStr(Trunc(VIEW.FramesPerSecond))+' FPS';

    if Assigned(delBeh) then begin
    delBeh.Behaviours.Clear;
    delBeh := nil;
    end;

    Spheres[countSpheres] := TGLSphere(DC1.AddNewChild(TGLSphere));

    with Spheres[countSpheres] do
    begin
    name := 'Spheres_'+IntToStr(countSpheres);;
    radius := 0.01;

      position.x := centroXlancador   + RandomRange(-5,5) * 0.2 * raiolancador ;
      position.y := centroYlancador   + RandomRange(-5,5) * 0.2 * raiolancador ;
      position.z := centroZlancador   + RandomRange(-5,5) * 0.2 * raiolancador ;
      alvo:= AffineVectorMake(alvoX,alvoY,alvoZ);
      Direction.AsAffineVector:= VectorNormalize(VectorSubtract(alvo,position.AsAffinevector));
    
      if countSpheres <= trunc(NmaxSpheres/4) then
        begin
          Material.FrontProperties.Emission.Color:=clrBlue;
          velocitySphere:= 3;
        end
      else
        begin
           Material.FrontProperties.Emission.Color:=clrRed;
           velocitySphere:=  10;
         end;
    
      totalTime:= totalTime + deltaTime;
      edTotalTime.Text:= FloattoStrF(totalTime,ffFixed,10,1);
    end ;      //   else do  if countSpheres <= trunc(NmaxSpheres/3) then
    

    CreateDynamicBehaviour_Sphere_Velocity (dynSphere,Spheres[countSpheres],velocitySphere);

    Inc(countSpheres);
    edcountSpheres.text := FloattoStrF(countSpheres, ffFixed, 10, 1);
    pnlDimensoesGL.Repaint;
    GLODEManager1.Step(deltaTime);
    VIEW.Update ;
    end;
    end;

     
  • Jerome.D (BeanzMaster)

    Hi Sergio, humm difficult to tell what is wrong but from the sample above.
    1st advice : Don't Create directly object at runtime in Cadencer progess function
    2nd : "edTotalTime.Text:=:"; "edcountSpheres.text:=" place there in a TTimer instead
    3rd : Instead of VIEW.Update ; use Invalidate

    An Another question whats the FPS Without ODE ?

    Another thing disable .$DEFINE GLS_LOGGING} in GLScene.Inc. By Using Looger, performance decrease

     

    Last edit: Jerome.D (BeanzMaster) 2017-06-10
  • Sergio

    Sergio - 2017-06-10

    Hi Jerome Thanks for the indications . I started to do a new cleaner code following the several suggestions. I started creating, as base for the new code, the sample GLSviewer because there are several good resources there.
    I inserted in GLSviewer code the lines of sample Skeletal with actor. It is working properly but I have some doubts and things to correct. Maybe you can help me.
    The code is attached (Delphi Seattle + GLscene). If you compile and run it you will see the GLSviewer screen plus a panel to control the actor (upper part.)
    Check the box ANIMATE and the actor will appear walking with good FPS.

    DOUBT 1) When I try to chnge "walk" by "run" or check the other boxes to jump , it does not work because the small panel (and other functions of GLSviewer became "disabled". I did not insert anything to disable the functions. Possibly is something inside GLSviewer . I could not find where the problem is.

    Doubt 2) FormMouseWheel works well for mesh objects . How to do to make it work for non-me objects ? T tried to remove the line " if ffObject.MeshObjects.Count > 0 then" but the result was not good.

    Other points: I am tryig to include a path control for the actor ( I wil need this after)
    Now I will start to inclusde the components of my previous code here to see how things wil work.

    By the way: can anyone tell me where I can find other models of "actors" different fro the ones in the GLscene samples ?

     
  • Jerome.D (BeanzMaster)

    Hi Sergio i taked a look to your sample, just some minors change ( cosmetics refines)
    but not see a real problem it run well on my pc with Lazarus (take the "Examples/editors/scenemaster" as base and it turn around between 360 and 400fps in debug mode (i've a NVidia GTX 1070 8go)

    procedure TMainForm.FormCreate(Sender: TObject);
    begin
      inherited;
      GetCurrentDir;
      NavCube := TGLNavCube.CreateAsChild(GLScene.Objects);
      NavCube.SceneViewer := GLSViewer;
      NavCube.Camera:=Camera1;
      NavCube.ActiveMouse:=True;
     // NavCube.AutoRotate:=False;
      NavCube.FPS := 30;
    
     // instantiate our specific hidden-lines shader
     // hlShader := THiddenLineShader.Create(Self);
      ffObject.IgnoreMissingTextures := True;
    
      Screen.Cursors[crLightxy] := LoadCursorFromRes('LIGHTXY');
      Screen.Cursors[crLightyz] := LoadCursorFromRes('LIGHTYZ');
      Screen.Cursors[crLightxz] := LoadCursorFromRes('LIGHTXZ');
      Screen.Cursors[crSlidexy] := LoadCursorFromRes('SLIDEXY');
      Screen.Cursors[crSlidexz] := LoadCursorFromRes('SLIDEXZ');
      Screen.Cursors[crSlideyz] := LoadCursorFromRes('SLIDEYZ');
      Screen.Cursors[crRotate]  := LoadCursorFromRes('ROTATE');
      Screen.Cursors[crZoom]    := LoadCursorFromRes('ZOOM');
      Screen.Cursors[crSlidezy] := LoadCursorFromRes('SLIDEZY');
    end;
    
    procedure TMainForm.FormShow(Sender: TObject);
    begin
      ShowCameraLocation;
      ShowFocalLength;
      ShowTargetLocation;
      ShowLightLocation;
    
      OpenDialog.Filter := VectorFileFormatsFilter;
      SaveDialog.Filter := VectorFileFormatsSaveFilter;
    
      ASyncTimer.Enabled:=true;
      //ApplyFSAA;
      //ApplyFaceCull;
      //ApplyFPS;
    end;  
    
    procedure TMainForm.CadencerProgress(Sender: TObject; const deltaTime,
      newTime: Double);
    begin
      if NavCube.InactiveTime > 5 then
      begin
        if NavCube.InactiveTime < 8 then
          Camera1.TurnAngle := Camera1.TurnAngle + (NavCube.InactiveTime - 5) * deltaTime * 2
        else
          Camera1.TurnAngle := Camera1.TurnAngle + deltatime * 6;
      end;
      GLSViewer.Refresh;
      if Self.Focused then
        GLSViewer.Invalidate;
    end;   
    
    // TGLASyncTimer instead of TTimer
    procedure TMainForm.ASyncTimerTimer(Sender: TObject);
    begin
      ShowCameraLocation;
      ShowFocalLength;
      ShowTargetLocation;
      ShowLightLocation;
      MainStatusBar.Panels[4].Text := Format('%.1f  FPS', [GLSViewer.FramesPerSecond]);
      GLSViewer.ResetPerformanceMonitor;
    end;  
    
    procedure TMainForm.btnActorBlendClick(Sender: TObject);
    begin
         if chkActorBlend.Checked then begin
          AnimationControler1.Actor:=GLActor1;
          TrackBar1Change(Self);
       end else AnimationControler1.Actor:=nil;
    end;
    
    procedure TMainForm.btnJumpHighClick(Sender: TObject);
    begin
      GLActor1.SwitchToAnimation(4, True);
    end;
    
    procedure TMainForm.btnJumpLongClick(Sender: TObject);
    begin
      GLActor1.SwitchToAnimation(3, True);
    end;
    
    procedure TMainForm.btnLoadActorClick(Sender: TObject);
    var pathMainDir :string;
    begin
       pathMainDir:=ExtractFilePath(Application.ExeName);
       SetCurrentDir( pathMainDir+'Media') ;
       with GLActor1 do
       begin
         LoadFromFile('trinityRage.smd');
         AddDataFromFile('walk.smd');
         Animations[1].MakeSkeletalTranslationStatic;
         AddDataFromFile('run.smd');
         Animations[2].MakeSkeletalTranslationStatic;
         AddDataFromFile('long_jump.smd');
         AddDataFromFile('jump.smd');
         AddDataFromFile('look_left_right.smd');
         Animations[5].MakeSkeletalRotationDelta;
         AnimationControler1.AnimationName:='look_left_right';
         OverlaySkeleton:=True;
         baseAnimation:='run';
         SwitchToAnimation(baseAnimation);
         Scale.X:= 0.05;                                      // SFC
         Scale.Y:= 0.05;                                      // SFC
         Scale.Z:= 0.05;                                       // SFC
         Position.X:= 0;                                      // SFC
         Position.Y:= BoundingSphereRadius;            // SFC
         Position.Z:= 0;
       end;
       if chkActorAnimate.Checked then
       begin
         GLActor1.AnimationMode := aamLoop;
       end
     else
       begin
        GLActor1.AnimationMode := aamNone;
       // Cadencer.Enabled := false;
       // timer.Enabled:= false;
       end;
       GLActor1.StructureChanged;
    end;
    
    procedure TMainForm.btnRunClick(Sender: TObject);
    begin
      baseAnimation:='run';
      GLActor1.SwitchToAnimation(baseAnimation, True);
    end;
    
    procedure TMainForm.btnWalkClick(Sender: TObject);
    begin
      baseAnimation:='walk';
      GLActor1.SwitchToAnimation(baseAnimation, True);
    end;  
    

     

    Last edit: Jerome.D (BeanzMaster) 2017-06-10
  • Jerome.D (BeanzMaster)

    When I try to chnge "walk" by "run" or check the other boxes to jump , it does not work because the small panel (and other functions of GLSviewer became "disabled". I did not insert anything to disable the functions. Possibly is something inside GLSviewer . I could not find where the problem is.

    ouch, i'm remember it is due to the fu....ing "mouse.CursorPos := " lines code in navcube unit.
    This make you lost focus, and cause many trouble with mouse just try the "Alt-Tab" shortcut and move mouse

    So this is the NavCube unit i've modified for Lazarus

     

    Last edit: Jerome.D (BeanzMaster) 2017-06-10
  • Sergio

    Sergio - 2017-06-11

    Hi Jerome First of all thank you very much for your help above. I followed your suggestions and it worked well. The file is attached. I included also a kind of path control for the actor.
    Really, as you mentioned, the jump , run and other buttons stopped to be "disabled" only after I changed the unit UNavCube of the GLSviewer sample by your version.
    Using the one in the original sample does not work.
    For the path control, I added the TGLmovement using what is in the sample Behaviors \ Path Control . The basic thing work but I need to adapt it to use with the actor.

    My doubts are:
    Doubt 1) I inserted a path using the nodes showed in the attached code . The actor does the path just one time returning to the original position. How to use TGLmovement to maintain the actor repeating the path automatically without stopping? If I wanted to do only 2 or 3 times I could doa loop but I imagine that the component has some property to to do the repetitions.

    Doubt 2) When the actor is walking, . is not looking straight in the same direction of the TGLmovement. It is not also remaining in the “vertical” position. How to maintain the actor looking more or less well to the path ? ( the ideal would be walking in the white line)

    Doubt3) I adjusted manually the actor1.Position.Y in such a way that the feet touch the floor (gridXYZ). Using the bounding sphere do not work well. Is there any way to do it automatically?

    Doubt 4) I am trying now to find a way (using collisions) to make the actor to deviate from the obstacle (GLsuperellipsoid) Just in the middle of the path making it to deviate and returning to the original programed path. The idea is to deviate walking through the side or simply jumping. If anyone have a simple code from some game it is welcome. I will post the final code result, when working, here.

    Thanks again

     
  • Jerome.D (BeanzMaster)

    Hi Sergio,

    I'll try TGLMovement is a little straight i think

    Doubt 1)

    Doubt 2) Yep one of the solution is to set Rotation for each node, and add many many more node (check CampPath demo in examples branch, it use simple TGLLine but concept is the same
    I've not managed to do the work properly (the best i give is with a DummyCube that follow node path and DummyCube as parent of Actor by setting correctly there Pitch and Roll property

    in cadencer i added this

    Movement := GetMovement(GLActor1);
    // pathcreated just check if Path is Created else get AV 
      if chkPath.Checked and pathcreated then
      begin
        Step:=Movement.Paths.Items[0].CurrentNodeIndex;
        if Step <= Movement.Paths.Items[0].Nodes.Count-1 then
        begin
         //   GLCube1.Position.SetPoint(GLLines2.Nodes.Items[step].AsVector);
            DCFollowCube.Position.SetPoint(Movement.Paths.Items[0].Nodes.Items[step + 1].PositionAsVector);
    
            //Points cube to the next point on the camera path
            DCActor.PointTo( DCFollowCube,YHmgVector);
    
         end
         else
          begin
            Step := 0;
          end;   
    

    2nd solution improve TGLMovement for make more soft travel; by compute (base on quadratic --> eg 4 points angle (up and direction) or one of Turn, Roll, Picth angle.

    I tried this in GLMovement.Pas; Take a look in the comment code.
    I'm near the solution but it will be in the procedure who compute the actual position on the path. But don't found yet where it is hidden.
    I've also a doubt with my formulas i don't sure there right i'm not good enough in math. If someone can check :)

    //Calculate functions add into this method
    procedure TGLMovement.DoProgress(const progressTime : TProgressTimes);
    var
      Path: TGLMovementPath;
      AngleVect : TAffineVector;
      Idx :Integer;
      NodePoint1, NodePoint2,
      NodePoint3, NodePoint4 : TGLPathNode;
      TempNode : TGLPathNode;
    
      absDir, absRight, absUp: TVector;
    
    begin
      if (FActivePathIndex >= 0) and (Paths[FActivePathIndex].InTravel) then
        begin
          Path := Paths[FActivePathIndex];
          Path.CalculateState(progressTime.newTime);
          if Assigned(Path.CurrentNode) then
          begin
            NodePoint1 :=Path.CurrentNode;
    
            if Owner.Owner is TGLBaseSceneObject then
              with TGLBaseSceneObject(Owner.Owner) do
              begin
                case Path.FRotationMode of
                  rmTurnPitchRoll:
                  begin
                    (*    EXPERIMENTAL CODE
    
                     Idx := Path.CurrentNodeIndex;
                     if idx < Path.Nodes.Count-1 then
                     begin
                       NodePoint4 := Path.Nodes.Items[Idx+1];
                       AngleVect := VectorAngleLerp(AffineVectorMake(NodePoint1.PositionAsVector),AffineVectorMake(NodePoint4.PositionAsVector),progressTime.deltaTime);
    
    // OR ???
    //VectorLerp(AffineVectorMake(NodePoint1.PositionAsVector),AffineVectorMake(NodePoint4.PositionAsVector),progressTime.deltaTime);
    
                       // PitchAngle := RadToDeg(AngleVect.V[0]);
                       // TurnAngle := RadToDeg(AngleVect.V[1]); OR ????
                        RollAngle := AngleVect.V[2];
                     end;
    
                   Idx := Path.CurrentNodeIndex;
                    NodePoint4 := TempNode;
                    if Idx>3 then
                    begin
                      NodePoint3 := Path.Nodes.Items[Idx-1];
                      NodePoint2 := Path.Nodes.Items[Idx-2];
                      NodePoint1 := Path.Nodes.Items[Idx-3];
                    end
                    else
                    begin
                      NodePoint3 := Path.Nodes.Items[Idx+1];
                      NodePoint2 := Path.Nodes.Items[Idx+2];
                      NodePoint1 := Path.Nodes.Items[Idx+3];
                    end; *)
    
                    Position.AsVector := Path.CurrentNode.FPosition;
                    Scale.AsVector    := Path.CurrentNode.FScale;
    
                   PitchAngle := Path.CurrentNode.PitchAngle;
                    TurnAngle := Path.CurrentNode.TurnAngle;
                    RollAngle := Path.CurrentNode.RollAngle;
    
                  end;
    
                  rmUpDirection:
                  begin
                  // first compute absolute attitude for pointing
                  (*  EXPERIMENTAL CODE
    
                    NodePoint1 :=Path.CurrentNode;
                    Idx := Path.CurrentNodeIndex;
                    NodePoint4 := Path.Nodes.Items[Idx+1];
                    absDir := VectorSubtract(NodePoint4.PositionAsVector, NodePoint1.PositionAsVector);
                    NormalizeVector(absDir);
    
                    // YHmgVector value must be set thrue a property
                    absRight := VectorCrossProduct(absDir,YHmgVector);
                    NormalizeVector(absRight);
                    absUp := VectorCrossProduct(absRight, absDir); *)
    
                    Position.AsVector := Path.CurrentNode.FPosition;
                    Scale.AsVector    := Path.CurrentNode.FScale;
                   // Direction.AsVector := absDir;
                   // Up.AsVector := absUp;
    
                    Direction.AsVector := Path.CurrentNode.FDirection;
                    Up.AsVector := Path.CurrentNode.FUp;
                  end;
                else
                  Assert(False, glsErrorEx + glsUnknownType);
                end
              end;
          end;
        end;
    end; 
    

    Doubt3)) Yes check terrain heightfield demos and on this forum. a topic exist wich was not published a long time ago about this

    Doubt 4) Take a look at the SphereSweep demo in Examples branches

    See you soon ;)

     

    Last edit: Jerome.D (BeanzMaster) 2017-06-13
  • Sergio

    Sergio - 2017-06-15

    Hi Jerome Thank you for your suggestions. I am working with them and advanced in some points but not in all. Next days I will post here a new code version with improvements. I am trying to include all the “concepts” and do some tests before bringing the components of my previous code into here. Remember that this discussion stared because the FPS of my previous code was very low.
    To maintain the actor in the vertical was easy and needed only to use the Rotate as (0,0,0) I all the nodes. To make the loop continuous needs only to do Path.Looped := True; About making the feet of the actor touch the floor I think the best thing is to do “manually” adjusting the height. For the collisions, you will see in the next code. I am trying to replace the GLODEDynamic I used in the previous code by the NGDdynamic used in Newton examples. Is there any advantage?
    My main doubt is about the use of TGLmovements. I read the code and seems to have some possibilities inside that are not accessible. The only thing I need to have the actor looking straight to the path is to set the movement Direction equal to the actor UP property ( or maybe using PointTo. The problem is that it seems that the movement Direction is not accessible. Inside the procedure
    I saw there the function GetPositionCoordinate and the function GetDirectionCoordinate but the question is: how to use them ?
    I will write soon. Cheers

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.