Menu

Problems with GLAsm navigation cube for GLViewer

Help
2017-03-14
2017-03-28
  • Ørjan Nilsen

    Ørjan Nilsen - 2017-03-14

    The new navigation cube is very useful but it seems to be some problems with it in the Samples\Delphi\AdvDemos\GLSViewer project:

    • If the navcube is enabled before some file is opened, all the buttons on the toolbar become unresponsive.
    • If the navcube is enabled, disabled and enabled again (pressing the toolbar icon), you get an invalid pointer operation. It looks like the navcube gets freed on disable and not created again on enable.
    • If you open a file, enable the navcube and then opens a second file, the navcube become unresponsive.
     
  • Jerome.D (BeanzMaster)

    Hi Ørjan Nilsen, in unavCube.pas try to replace procedure TGLNCube.DoProgress(const pt: TProgressTimes); by the following code. (Just some minor change)

    procedure TGLNCube.DoProgress(const pt: TProgressTimes);
    const
      tb: array [0 .. 1] of array [0 .. 3] of TVector = (((x: 0; y: 20; z: 1;
        W: 0), (x: 1; y: 20; z: 0; W: 0), (x: 0; y: 20; z: - 1; W: 0), (x: - 1;
        y: 20; z: 0; W: 0)), ((x: 0; y: - 20; z: 1; W: 0), (x: 1; y: - 20; z: 0;
        W: 0), (x: 0; y: - 20; z: - 1; W: 0), (x: - 1; y: - 20; z: 0; W: 0)));
    var
      mp: TPoint;
      mover: boolean;
      i: Integer;
      v0, v1, v2, v: TVector;
      obj: TGLBaseSceneObject;
    
    procedure moveTo(trgv: TVector);
    begin
      FPosAnimationStart := FCam.Position.AsVector;
      FPosAnimationEnd := FCam.TargetObject.AbsoluteToLocal
        (VectorScale(VectorNormalize(trgv), FCam.DistanceToTarget));
      FDelta := 0;
    end;
    
    begin
      if not (csloading in componentstate) then
      begin
      mp := FViewer.ScreenToClient(mouse.CursorPos);
      mover := (mp.x > FHud.Position.x - 64) and (mp.x < FHud.Position.x + 64) and
        (mp.y > FHud.Position.y - 64) and (mp.y < FHud.Position.y + 64);
      // mouse Down/Up
      if FDelta > 1 then
      begin
        if iskeydown(VK_LBUTTON) and (not FMouseRotation) then
        begin
       //    selection > start auto rotation
          if mover and (FSel >= 0) then
          begin
            v.z:=0;
            v.x:=0;
            if (FCam.TargetObject<>nil) then v := FCam.AbsoluteVectorToTarget;
            v.y := 0;
            if v.x < 0 then
              i := -1
            else
              i := 1;
            i := round((ArcCosine(VectorAngleCosine(v, ZHmgPoint)) * i + PI) / PI
              * 2) mod 4;
            if (FSel = 4) or (FSel = 5) then
              moveTo(tb[FSel - 4][i])
            else
              moveTo(FSelPos);
            FInactiveTime := 0;
          end // start manual rotation
          else
          if FMouse then
          begin
    
            FMouseRotation := true;
            FMousePos := mouse.CursorPos;
    
            mouse.CursorPos := point(sW2, sH2);
            FInactiveTime := 0;
          end;
        end;
        // stop rotation, restore cursor
        if (not iskeydown(VK_LBUTTON)) and FMouseRotation and FMouse then
        begin
          FMouseRotation := false;
          mouse.CursorPos := FMousePos;
    
          FInactiveTime := 0;
        end;
      end
      // auto rotation progress
      else
      begin
        FDelta := FDelta + pt.deltaTime * 2;
        v := VectorLerp(FPosAnimationStart, FPosAnimationEnd,
          FDelta * FDelta * (3 - 2 * FDelta));
        v := VectorScale(VectorNormalize(v), VectorLength(FPosAnimationStart));
        if FDelta < 1 then
          FCam.Position.SetPoint(v)
        else
          FCam.Position.SetPoint(FPosAnimationEnd);
    
        v := VectorScale(VectorNormalize(v), 10);
        if FDelta < 1 then
          v := VectorScale(VectorNormalize(v), 10)
        else
          v := VectorScale(VectorNormalize(FPosAnimationEnd), 10);
        FNavCam.Position.SetPoint(v);
    
        for i := 2 to FCube.Count - 1 do
          with TGLSceneObject(FCube.Children[i]) do
            Material.FrontProperties.Diffuse.SetColor(tagfloat, tagfloat, 1);
        FInactiveTime := 0;
      end;
      FSel := -1;
      // manual rotation progress
      if FMouseRotation and FMouse then
      begin
    
        mp := mouse.CursorPos;
        if (FCam <> nil) and (FCam.TargetObject<>nil) then
          FCam.MoveAroundTarget((sH2 - mp.y) * 0.2, (sW2 - mp.x) * 0.2);
        FNavCam.MoveAroundTarget((sH2 - mp.y) * 0.2, (sW2 - mp.x) * 0.2);
        mouse.CursorPos := point(sW2, sH2);
    
        FInactiveTime := 0;
      end
      else if FReady then
      begin
        // selection
        if mover and (FDelta > 1) then
        begin
          v0 := FNavCam.AbsolutePosition;
          v1 := FMem.Buffer.ScreenToVector(mp.x - round(FHud.Position.x) + 64,
            round(FHud.Position.y) - mp.y + 64);
          SetVector(v2, 99999, 99999, 99999);
    
          obj := nil;
          for i := 2 to FCube.Count - 1 do
            with TGLSceneObject(FCube.Children[i]) do
            begin
              Material.FrontProperties.Diffuse.SetColor(tagfloat, tagfloat, 1);
              if RayCastIntersect(v0, v1, @v) then
                if VectorDistance2(v2, v0) > VectorDistance2(v, v0) then
                begin
                  SetVector(v2, v);
                  FSel := FCube.Children[i].tag;
                  FSelPos := FCube.Children[i].Position.AsVector;
                  obj := FCube.Children[i];
                end;
            end;
          if FSel >= 0 then
          begin
            FViewer.cursor := -21;
            TGLSceneObject(obj).Material.FrontProperties.Diffuse.SetColor
              (1, 0.6, 0);
          end
          else
            FViewer.cursor := 0;
        end;
        v := VectorScale(VectorNormalize(FCam.AbsoluteVectorToTarget), 10);
        FNavCam.Position.SetPoint(VectorNegate(v));
        FInactiveTime := FInactiveTime + pt.deltaTime;
      end;
      // rendering
      FTimer := FTimer + pt.deltaTime;
      if FTimer > 1 / FFps then
      begin
        FTimer := FTimer - floor(FTimer * FFps) / FFps;
        FMem.Render(FCube);
        FMem.CopyToTexture(FHud.Material.Texture);
        FReady := true;
      end;
      end;
    end;
    
     
  • Ørjan Nilsen

    Ørjan Nilsen - 2017-03-15

    Hi Jerome

    You have a different class name than I have. In my copy of the code it’s TGLNavCube not TGLNCube.
    Anyway replacing the DoProgress procedure did not fix any of the tree issues I described. I think at least part of the issue must be addressed in GLSViewer\Source\fMain.pas

    Ørjan

     
  • Jerome.D (BeanzMaster)

    Hi, i tried under Lazarus and i've the same behaviour so. after some litte research, the cause is du to the mouse.CursorPos := point(sW2, sH2); this line set mouse cursor position and making lost Focus on other controls

    So this is the correction :
    PS : I let and commented the "old" code :

    procedure TGLNavCube.DoProgress(const pt: TProgressTimes);
    const
      tb: array [0 .. 1] of array [0 .. 3] of TVector = (((x: 0; y: 20; z: 1;
        W: 0), (x: 1; y: 20; z: 0; W: 0), (x: 0; y: 20; z: - 1; W: 0), (x: - 1;
        y: 20; z: 0; W: 0)), ((x: 0; y: - 20; z: 1; W: 0), (x: 1; y: - 20; z: 0;
        W: 0), (x: 0; y: - 20; z: - 1; W: 0), (x: - 1; y: - 20; z: 0; W: 0)));
    var
      mp: TPoint;
      mover: boolean;
      i: Integer;
      v0, v1, v2, v: TVector;
      obj: TGLBaseSceneObject;
    
    procedure moveTo(trgv: TVector);
    begin
      FPosAnimationStart := FCam.Position.AsVector;
      FPosAnimationEnd := FCam.TargetObject.AbsoluteToLocal
        (VectorScale(VectorNormalize(trgv), FCam.DistanceToTarget));
      FDelta := 0;
    end;
    
    begin
    //  if not (csloading in componentstate) then
    //  begin
      mp := FViewer.ScreenToClient(mouse.CursorPos);
      mover := (mp.x > FHud.Position.x - 64) and (mp.x < FHud.Position.x + 64) and
        (mp.y > FHud.Position.y - 64) and (mp.y < FHud.Position.y + 64);
      // mouse Down/Up
      if (mp.y<FViewer.Top) or (mp.x<FViewer.Left) or (mp.y>FViewer.Top+FViewer.Height) or (mp.x>FViewer.Left+FViewer.Width) then exit;
      if FDelta > 1 then
      begin
        if iskeydown(VK_LBUTTON) and (not FMouseRotation) then
        begin
          // selection > start auto rotation
          if mover and (FSel >= 0) then
          begin
    
            v := FCam.AbsoluteVectorToTarget;
            v.y := 0;
            if v.x < 0 then
              i := -1
            else
              i := 1;
            i := round((ArcCos(VectorAngleCosine(v, ZHmgPoint)) * i + PI) / PI
              * 2) mod 4;
            if (FSel = 4) or (FSel = 5) then
              moveTo(tb[FSel - 4][i])
            else
              moveTo(FSelPos);
            FInactiveTime := 0;
          end // start manual rotation
          else if FMouse then
          begin
            // ----> CHANGE HERE
            FMouseRotation := true;
            FMousePos := mouse.CursorPos;
            //FMousePos := point(sW2, sH2);
           // mouse.CursorPos := point(sW2, sH2);
            FInactiveTime := 0;
          end;
        end;
        // stop rotation, restore cursor
        if (not iskeydown(VK_LBUTTON)) and FMouseRotation and FMouse then
        begin
         // ----> CHANGE HERE
          FMouseRotation := false;
         // FMousePos := mouse.CursorPos;
         // mouse.CursorPos := FMousePos;
    
          FInactiveTime := 0;
        end;
      end
      // auto rotation progress
      else
      begin
        FDelta := FDelta + pt.deltaTime * 2;
        v := VectorLerp(FPosAnimationStart, FPosAnimationEnd,
          FDelta * FDelta * (3 - 2 * FDelta));
        v := VectorScale(VectorNormalize(v), VectorLength(FPosAnimationStart));
        if FDelta < 1 then
          FCam.Position.SetPoint(v)
        else
          FCam.Position.SetPoint(FPosAnimationEnd);
    
        v := VectorScale(VectorNormalize(v), 10);
        if FDelta < 1 then
          v := VectorScale(VectorNormalize(v), 10)
        else
          v := VectorScale(VectorNormalize(FPosAnimationEnd), 10);
        FNavCam.Position.SetPoint(v);
    
        for i := 2 to FCube.Count - 1 do
          with TGLSceneObject(FCube.Children[i]) do
            Material.FrontProperties.Diffuse.SetColor(tagfloat, tagfloat, 1);
        FInactiveTime := 0;
      end;
      FSel := -1;
      // manual rotation progress
      if FMouseRotation and FMouse then
      begin
    
        mp := mouse.CursorPos;
        if FCam <> nil then
        begin
        // ----> CHANGE HERE
          FCam.MoveAroundTarget((FMousePos.y - mp.y) * 0.02, (FMousePos.x - mp.x) * 0.02);
          FNavCam.MoveAroundTarget((FMousePos.y - mp.y) * 0.02, (FMousePos.x - mp.x) * 0.02);
    //    FCam.MoveAroundTarget((sH2 - mp.y) * 0.2, (sW2 - mp.x) * 0.2);
    //  FNavCam.MoveAroundTarget((sH2 - mp.y) * 0.2, (sW2 - mp.x) * 0.2);
        end;
    
       // mouse.CursorPos := point(sW2, sH2);
    
       FInactiveTime := 0;
      end
      else if FReady then
      begin
        // selection
        if mover and (FDelta > 1) then
        begin
          v0 := FNavCam.AbsolutePosition;
          v1 := FMem.Buffer.ScreenToVector(mp.x - round(FHud.Position.x) + 64,
            round(FHud.Position.y) - mp.y + 64);
          SetVector(v2, 99999, 99999, 99999);
    
          obj := nil;
          for i := 2 to FCube.Count - 1 do
            with TGLSceneObject(FCube.Children[i]) do
            begin
              Material.FrontProperties.Diffuse.SetColor(tagfloat, tagfloat, 1);
              if RayCastIntersect(v0, v1, @v) then
                if VectorDistance2(v2, v0) > VectorDistance2(v, v0) then
                begin
                  SetVector(v2, v);
                  FSel := FCube.Children[i].tag;
                  FSelPos := FCube.Children[i].Position.AsVector;
                  obj := FCube.Children[i];
                end;
            end;
          if FSel >= 0 then
          begin
            FViewer.cursor := -21;
            TGLSceneObject(obj).Material.FrontProperties.Diffuse.SetColor
              (1, 0.6, 0);
          end
          else
            FViewer.cursor := 0;
        end;
        v := VectorScale(VectorNormalize(FCam.AbsoluteVectorToTarget), 10);
        FNavCam.Position.SetPoint(VectorNegate(v));
        FInactiveTime := FInactiveTime + pt.deltaTime;
      end;
      // rendering
      FTimer := FTimer + pt.deltaTime;
      if FTimer > 1 / FFps then
      begin
        FTimer := FTimer - floor(FTimer * FFps) / FFps;
        FMem.Render(FCube);
        FMem.CopyToTexture(FHud.Material.Texture);
        FReady := true;
      end;
     // end;
    end;  
    

    Cheers

     

    Last edit: Jerome.D (BeanzMaster) 2017-03-21
  • Ørjan Nilsen

    Ørjan Nilsen - 2017-03-24

    Hi Jerome

    I just tried your code. With this version of TGLNavCube.DoProgress, the NavCube does not appear at all when I click the NavCube icon in GLSViewer.

     
  • Jerome.D (BeanzMaster)

    Uh ! ??? Have you the sample code you use, something else must not be correct. You are under Delphi or Lazarus ?

     
  • Ørjan Nilsen

    Ørjan Nilsen - 2017-03-24

    I Use Delphi 10.1. The sample code I use is this project svn://svn.code.sf.net/p/glscene/code/trunk/Samples/Delphi/AdvDemos/GLSViewer

    To activate the NavCube I click on the fourth icon (yellow with three axes) from right on the toolbar.

     
  • Jerome.D (BeanzMaster)

    Ok, have you tried the "Scene Master" project in examples/editor branch ? (its an update of GLSViewer demo)

     
  • Ørjan Nilsen

    Ørjan Nilsen - 2017-03-28

    I was not aware that the Examples branch existed. Although Scene Master use a different version of unavcube.pas, it looks like it have the same problems with the navcube.

     
  • Jerome.D (BeanzMaster)

    Humm ! Pavel can you check under Delphi because under Lazarus it work very well.

    Ørjan have you try make the changes with the latest code i posted here ?

     
  • Ørjan Nilsen

    Ørjan Nilsen - 2017-03-28

    The lastet code you posted fixes the first problem in my original post. Your code does not fix the two other problems. I think the second problem with invalid pointer operation must be fixed in fMain.pas

     
  • Pavel Vassiliev

    Pavel Vassiliev - 2017-03-29

    Nilsen,
    Yes, the problem is in mainForm of GLSceneViewer (or SceneMaster) and I've not found a decision yet, but the menu could be accessed by clicking right mouse button and after a file is opened then again click on NavCube menu button. And the cube is working then.
    Pavel

     

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.