GLScene комплектация

Я использовал GLSceneViewer1.Buffer.GetPickedObject( x, y), чтобы выбрать объекты GLscene в событии GLViewerMouseDown для демонстрации выбора. Мне нужно выбрать объект, изменить цвет щелчком левой кнопки мыши и отменить выделение другим щелчком левой кнопки мыши, а если выбран другой объект, он отменяется. Похоже, что TGLSceneObject нуждается в свойстве IsPicked: boolean, чтобы я мог этого добиться. Если кто-то знает, что делать это без модификации GLScene было бы здорово. Вот код, который я написал, вроде как работает, но вроде нет. SetSelected (Selected, SelectedColor) просто меняет цвет выделенного объекта.

procedure TForm32.GLSceneViewer1MouseDown( Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer );
  var
    Selected : TGLSceneObject;
    AButton : TGLMouseButton;
  begin
    AButton := TGLMouseButton( Button );

    // if an object is picked...
    Selected := ( GLSceneViewer1.Buffer.GetPickedObject( x, y ) as TGLSceneObject );

      case AButton of
        mbLeft:
          begin
              if( Selected <> UnSelected ) then
                begin
                   if( Assigned( Selected ) ) then
                      begin
                        SetSelected( Selected, SelectedColor );
                        StatusBar1.Panels[0].Text := 'Selected';
                        UnSelected := Selected;
                      end
                   else
                    if( not Assigned( Selected ) ) then
                      begin
                        UnSelected.Material.FrontProperties.Emission.Color:= clrBlack;
                        UnSelected.Material.FrontProperties.Ambient.Color := clrGray20;
                        UnSelected.Material.FrontProperties.Diffuse.Color := clrGray80;
                        StatusBar1.Panels[0].Text := 'Unselected';
                        UnSelected := Selected;
                      end;
                end;
          end;
      end;
  end;

Для меня это было бы проще:

procedure TForm32.GLSceneViewer1MouseDown( Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer );
  var
    Selected : TGLSceneObject;
  begin
    Selected := ( GLSceneViewer1.Buffer.GetPickedObject( x, y ) as TGLSceneObject );
      if( not Selected.IsPicked ) then
        SetSelected( Selected, SelectedColor )
      else
        SetSelected( Selected, UnSelectedColor );
   end;

1 ответ

Решение

После некоторых дискуссий о том, следует ли мне ломать библиотеку GLScene, изменяя исходный код, что потребует необходимости распространять исходный код, что мне не кажется идеальным, я пришел к следующему коду в качестве ответа на мою проблему. Казалось, ответ состоял в том, чтобы сохранить объект буфера TGLSceneObject, который я назвал CurrentSelection.

procedure TForm32.GLSceneViewer1MouseDown( Sender : TObject; Button : TMouseButton; Shift : TShiftState; X, Y : Integer );
  //CurrentSelection : TGLSceneObject; //TForm private declaration
  //Selected : TGLSceneObject; //TForm private declaration
  begin
    Selected := ( GLSceneViewer1.Buffer.GetPickedObject( x, y ) as TGLSceneObject );
      if( Selected <> nil ) then  //Avoid access violation error
        begin
          if( Assigned( CurrentSelection ) ) then //If CurrentSelection is not nil deselect it
            SetSelectedColor( CurrentSelection, UnSelectedColor );

          if( Selected = CurrentSelection ) then 
            begin 
              //has the same object been clicked then deselect it and clear the buffer object
              SetSelectedColor( Selected, UnSelectedColor );
              CurrentSelection := nil;
            end
          else
            begin 
              //if no object is selected select an object, set the color and assign the object to the buffer
              SetSelectedColor( Selected, SelectedColor );
              CurrentSelection := Selected;
            end;
        end;
  end;

Установить цвет объекта TGLSceneObject

procedure TForm32.SetSelectedColor( Selected : TGLSceneObject; Color : TColorVector );
  begin
    Selected.Material.FrontProperties.Ambient.Color := Color;
    Selected.Material.FrontProperties.Diffuse.Color := Color;
    Selected.Material.FrontProperties.Emission.Color:= clrBlack;
  end;

Приведенный выше код не проверяет, какая кнопка мыши была использована, но я могу выбрать объект, отменить выбор объекта, а когда выбран другой объект, он отменяет выбор текущего объекта.

Мне нужно будет изменить его, чтобы установить невыбранный объект в исходный цвет / материал, но это должно быть относительно просто.

Ура:)

Другие вопросы по тегам