フォーラム


ゲスト  

ようこそ ゲスト さん。このフォーラムに投稿するには 登録が必要です。

ページ: [1]
トピック: [QC#103139] TModel3D can not be proxy object
DEKO
管理者
投稿数: 2649
[QC#103139] TModel3D can not be proxy object
on: 2014/04/10 00:59 Thu

TProxyObject に TModel3D を指定しても表示されないというものです。

Report No: 103139 Status: Open
TModel3D can not be proxy object.
http://qc.embarcadero.com/wc/qcmain.aspx?d=103139
QCWIN:Defect_No=103139

 
設計時はともかく、"実行時にはどうにかする方法" を中山さん (a.k.a. luxidea) に教えて頂きました。

[uProxyObjectFix.pas]
unit uProxyObjectFix;

interface

uses
System.Types, FMX.Controls3D, FMX.Types;

type
TControl3Dhelper = class Helper for TControl3D
private
// Access Methods
function Get_Size: TPoint3D;
procedure Set_Size(const Value: TPoint3D);
function GetAbsolMatrix: TMatrix3D;
procedure SetAbsoluteMatrix(const Value: TMatrix3D);
// Methods
procedure RecalcChildrenAbsolute;
procedure RenderTree;
public
// Properties
property _Size: TPoint3D read Get_Size write Set_Size;
property AbsoluteMatrix: TMatrix3D read GetAbsolMatrix write SetAbsoluteMatrix;
end;

TProxyObject = class(FMX.Controls3D.TProxyObject)
protected
{ protected }
procedure Render; override;
end;

implementation

{ TControl3Dhelper }

function TControl3Dhelper.GetAbsolMatrix: TMatrix3D;
begin
result := Self.GetAbsoluteMatrix;
end;

function TControl3Dhelper.Get_Size: TPoint3D;
begin
result.X := FWidth;
result.Y := FHeight;
result.Z := FDepth;
end;

procedure TControl3Dhelper.RecalcChildrenAbsolute;
var
F: TFmxObject;
begin
if Assigned(Children) then
for F in Children do
if (F is TControl3D) then
(F as TControl3D).RecalcAbsolute;
end;

procedure TControl3Dhelper.RenderTree;
begin
RenderInternal;
end;

procedure TControl3Dhelper.SetAbsoluteMatrix(const Value: TMatrix3D);
begin
FAbsoluteMatrix := Value;
FRecalcAbsolute := False;
RecalcChildrenAbsolute;
end;

procedure TControl3Dhelper.Set_Size(const Value: TPoint3D);
begin
FWidth := Value.X;
FHeight := Value.Y;
FDepth := Value.Z;
end;

{ TProxyObject }

procedure TProxyObject.Render;
var
M: TMatrix3D;
S: TPoint3D;
begin
if Assigned(SourceObject) then
with SourceObject do
begin
M := AbsoluteMatrix;
S := _Size;
AbsoluteMatrix := Self.AbsoluteMatrix;
_Size := Self._Size;
SourceObject.RenderTree;
AbsoluteMatrix := M;
_Size := S;
end;
end;
end.

  
使い方は、interface セクションの uses の最後に uProxyObjectFix を追加するだけです。QC の Attachments のプロジェクトに uProxyObjectFix を追加すると効果を確認する事ができます。

DEKO
管理者
投稿数: 2649
Re: [QC#103139] TModel3D can not be proxy object
on: 2014/04/10 03:42 Thu

中山さんの説明によると…

  • プリミティブな 3D シェイプコンポーネントは TCustomMesh の派生コンポーネント
  • TModel3D は TDummy の派生コンポーネント
  • TModel3D は TDummy に TMesh 配列をぶら下げたもの。
  • TProxyObject の SourceObject に TCube 等のプリミティブ 3D シェイプコンポーネントを指定した場合には正しく動作する。
  • TProxyObject の SourceObject に TModel3D が指定された場合には TMesh 配列の位置情報も更新しなければならないのにそうなっていない。

という事らしいです。

○: TProxyObject.SourceObject => TCube (= TCustomMesh)
×: TProxyObject.SourceObject => TModel3D (= TDummy -> array of TMesh)

より正確に言えば「TProxyObject.SourceObject に指定されたコントロールに子コントロールがあれば、子コントロールの位置情報も更新しなくてはならない」という事のようです。

ページ: [1]
WP Forum Server by ForumPress | LucidCrew
バージョン: 1.7.5 ; ページロード: 0.031 sec.