GLS场景采摘
GLScene picking
我一直在使用 GLSceneViewer1.Buffer.GetPickedObject( x, y ) 在每个选择演示的 GLViewerMouseDown 事件中选择 GLscene 对象。我需要 select 一个对象,更改颜色,单击鼠标左键,然后再单击鼠标左键 deselect,如果另一个对象被 selected,则 deselect编辑。似乎 TGLSceneObject 需要一个 属性 IsPicked : boolean 对我来说能够实现这一点。如果有人知道在不修改 GLScene 的情况下这样做会很酷。这是我编写的代码,它可以工作,但不能。 SetSelected( Selected, SelectedColor ) 只是改变 selected 对象的颜色。
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;
在争论我是否应该通过修改源代码来破坏我的 GLScene 库,这将需要分发源代码,这对我来说似乎不太理想,我想出了以下代码作为回答我的问题。答案似乎是维护一个我命名为 CurrentSelection 的 TGLSceneObject 缓冲区对象。
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;
上面的代码不检查使用了哪个鼠标按钮,但我可以select一个对象,deselect这个对象,当另一个对象被select编辑时deselect当前对象。
我需要修改它以将 deselected 对象设置为其原始 colour/material 但这应该相对简单。
干杯:)
我一直在使用 GLSceneViewer1.Buffer.GetPickedObject( x, y ) 在每个选择演示的 GLViewerMouseDown 事件中选择 GLscene 对象。我需要 select 一个对象,更改颜色,单击鼠标左键,然后再单击鼠标左键 deselect,如果另一个对象被 selected,则 deselect编辑。似乎 TGLSceneObject 需要一个 属性 IsPicked : boolean 对我来说能够实现这一点。如果有人知道在不修改 GLScene 的情况下这样做会很酷。这是我编写的代码,它可以工作,但不能。 SetSelected( Selected, SelectedColor ) 只是改变 selected 对象的颜色。
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;
在争论我是否应该通过修改源代码来破坏我的 GLScene 库,这将需要分发源代码,这对我来说似乎不太理想,我想出了以下代码作为回答我的问题。答案似乎是维护一个我命名为 CurrentSelection 的 TGLSceneObject 缓冲区对象。
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;
上面的代码不检查使用了哪个鼠标按钮,但我可以select一个对象,deselect这个对象,当另一个对象被select编辑时deselect当前对象。
我需要修改它以将 deselected 对象设置为其原始 colour/material 但这应该相对简单。
干杯:)