using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Sharp3D.Math.Core;
using Sharp3D.Math.Geometry3D;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using HelpTools;
namespace Editor
{
public class IFile
{
}
// 全局唯一值,用來記錄其他物品
public struct GIID
{
public GIID(int id, GIIDMng giidmng)
{
m_id = id;
m_giid_mng = giidmng;
}
public GIID(int id) { m_id = id; m_giid_mng = null; }
// 獲得唯一值
public int value { get { return m_id; } }
// 所記錄的唯一值
int m_id;
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is GIID)
{
return this.m_id == ((GIID)obj).m_id;
}
return false;
}
// 所記錄的唯一值
public static bool operator ==(GIID giid1, GIID giid2)
{
return giid1.m_id == giid2.m_id;
}
public static bool operator !=(GIID giid1, GIID giid2)
{
return !(giid1 == giid2);
}
public override string ToString()
{
return m_giid_mng.getIDString(this);
}
public void Parse(string id_string)
{
m_giid_mng.setIDString(this, id_string);
}
GIIDMng m_giid_mng;
}
// 全局唯一值管理器
// 沒有完成
public class GIIDMng
{
public GIIDMng()
{
}
// 生成一個全局唯一值
public GIID getGIID()
{
GIID giid = new GIID(m_id_acc++, this);
m_map[giid] = Guid.NewGuid().ToString();
return giid;
}
public bool getGIID(string id_string, out GIID giid)
{
foreach (KeyValuePair<GIID, string> pair in m_map)
{
if (pair.Value == id_string)
{
giid = pair.Key;
return true;
}
}
giid = new GIID();
return false;
}
public void setIDString(GIID id, string id_string)
{
m_map[id] = id_string;
}
public string getIDString(GIID id)
{
return m_map[id];
}
// 删除一個全局唯一值
public void removeGIID(GIID id)
{
if (m_map.ContainsKey(id))
{
m_map.Remove(id);
}
}
public void Clear()
{
m_map.Clear();
//m_id_acc = 0;
}
int m_id_acc = 0;
Dictionary<GIID, string> m_map = new Dictionary<GIID, string>();
// 地圖編輯器社群使用,其他慎用!
public void SetNextGiid(int next)
{
if (next <= m_id_acc)
return;
else
m_id_acc = next;
}
}
// 物品memento,用物品屬性清單建構
public class ActorMemento : IMemento
{
public Dictionary<String, String> m_property_dic = new Dictionary<string, string>();
}
public enum ActorFlag
{
UNDELETEABLE = 0x01, //是否可以删除
UNEDITABLE = 0x02, //是否可以編輯
UNSELECTABLE = 0x04, //是否可以選擇
UNMOVEABLE = 0x08, //是否可以移動
UNSERIALIZABLE = 0x10,//是否可以序列化
UNCOPYPASTABLE = 0x20,//是否可以複制粘貼
}
public interface ISelectableObject
{
// 滑鼠懸浮
bool mouseHover(Rect<int> rect, IView view);
// 滑鼠選擇
bool mouseSelect(Rect<int> rect, IView view);
}
public interface ITransformableObject
{
// 移動物品
void move(Vector3F v);
// 移動到指定位置
void moveTo(Vector3F pos);
// 旋轉
void rotate(Vector3F pos, Vector3F axis, float angle);
// 縮放
void scale(Vector3F scale_var);
// 對齊
void align(IActor dst_actor, bool x_axis, bool y_axis, bool z_axis);
}
//物品類型枚舉,炫舞1編輯器從炫舞2修改而來,遺留了很多無用或者不合适的定義和資料結構,這裡重新定義一個枚舉是為了減少之前的雜亂和引進的錯誤
public enum ACTOR_TYPE
{
AT_DML,
AT_CHR,
AT_ACTOR,
AT_NEWACTOR,
AT_SPE,
AT_SOUND,
AT_AINODE,
AT_LIGHT,
AT_GROUP,
AT_END
}
// 物品接口類
public interface IActor : ISelectableObject, ITransformableObject, IDisposable
{
// 複制
IActor clone(IEditItem edititem);
// 獲得子物品容器,如果沒有子物品容器傳回null
IActorLayerMng getActorBuffer();
// 2D的矩形位置
Rect<int> rect { get; set; }
//scale
Vector3F Scale { get; }
// 3D位置矩陣
Matrix4F locationmat { get; set; }
// 包圍盒
AxisAlignedBox aabb { get; set; }
// 中心
Vector3F center { get; set; }
// 是否隐藏
bool hide { get; set; }
// 是否當機
bool freeze { get; set; }
// 是否顯示名稱
bool canDisplayName { get; set; }
// 所屬物品層
IActorLayerMng parentLayer { get; set; }
// 父物品
IActor parent { get; set; }
// 物品名稱
string name { get; set; }
//是否生成陰影
bool genlightmap { get; set; }
//是否投射(實時)陰影
bool castshadow { get; set; }
//獲得标志
int flag { get; }
// 獲得設定memento
IMemento getMemento(int mode);
void setMemento(IMemento mem);
// 更新
void update(int t);
void UpdateCpuSkin(float t);
// 繪制
void render(int t, ClientBridge.ClientRenderSys rendersys);
// 繪制包圍盒
void renderAABB(int t, ClientBridge.ClientRenderSys rendersys, Color color);
// 繪制坐标軸
void renderCoordinate(int t, ClientBridge.ClientRenderSys rendersys);
// 繪制圓
void renderCircles(int t, ClientBridge.ClientRenderSys rendersys);
// 全局唯一ID,主要用來儲存連結的内容
GIID giid { get; }
// 物品移動控制軸對應的ID
List<GIID> giid_move { get; }
// 物品旋轉控制圓對應的ID
List<GIID> giid_rotate { get; }
// 獲得key/value的清單
IDictionary<String, String> getPropertyList();
// 更改key所對應的value
void notifyPropertyChange(String key, String value);
// edititem用來獲得可能需要的資訊
// 讀取/儲存物品資訊到xml節點中
bool serialize(System.Xml.XmlNode xmlnode, IEditItem edititem, bool load, bool clipboard);
// 讀取/儲存物品資訊到檔案中
bool serialize(IFile file, IEditItem edititem, bool load);
// 儲存物品
bool serialize(BinaryWriter binWriter);
// 讀取物品
bool serialize(BinaryReader binReader, IEditItem edititem);
// 移動物品
new void move(Vector3F v);
// 移動到指定位置
new void moveTo(Vector3F pos);
// 旋轉
new void rotate(Vector3F pos, Vector3F axis, float angle);
// 縮放
new void scale(Vector3F scale_var);
void scaleForPar(Vector3F scale_var);
// 設定物品位置,并更新物品包圍盒
void updateLocationAABB();
// 将物品加入到硬體選擇
void pushHardwareSelect(ClientBridge.ClientRenderSys rendersys);
// 将線模型加入到硬體選擇
void pushLineHardwareSelect(ClientBridge.ClientRenderSys rendersys);
// 将移動控制軸加入到硬體選擇
void pushHardwareSelect_Move(ClientBridge.ClientRenderSys rendersys);
// 将旋轉控制圓加入到硬體選擇
void pushHardwareSelect_Rotate(ClientBridge.ClientRenderSys rendersys);
// 得到物品類别字元串
string getActorTypestr();
//父物品層Hide操作回調
void notifyLayerHide(bool isHide);
//父物品層Freeze操作回調
void notifyLayerFreeze(bool isFreeze);
//擷取物體是否可見
bool isVisible();
//得到物品類型
ACTOR_TYPE GetActorType();
//删除一個模型時,會從管理器中拿走,在從管理器拿走之前做一些必要的重置操作
//目前用到該地方的是寶寶和坐騎綁定,在釋放坐騎時要将和寶寶的綁定關系重置
void DoBeforeDel();
}
// 物品的實作輔助基類,用來實作若幹預設物品的接口,友善物品接口的實作
// 實作IActor的類不是必須要繼承這個類!
public class ActorBase : IXmlSerial
{
protected GIID m_giid = new GIID();
List<GIID> m_move_giid = new List<GIID>(); // 為物品移動控制軸提供六個ID,以控制移動方向
List<GIID> m_rotate_giid = new List<GIID>(); // 為物品旋轉控制圓提供3個ID,以控制旋轉方向, fixme:目前繞三個軸旋轉
Rect<int> m_rect = new Rect<int>(); // 2d矩形位置,界面編輯器用
bool m_hide = false; // 是否隐藏
bool m_freeze = false; // 是否當機
protected Dictionary<String, String> m_property_dic = new Dictionary<string, string>(); // 屬性清單
Matrix4F m_locationmat = Matrix4F.Identity; // 3d位置矩陣
protected AxisAlignedBox m_aabb = new AxisAlignedBox(); // 包圍盒
protected Vector3F m_center = new Vector3F(); // 物品中心(移動、旋轉軸),暫時為包圍盒中心,在更新包圍盒的同時更新物品中心
IActor m_parent = null; // 物品屬于哪個父物品(Group、Prefeb)
public virtual IActorLayerMng getActorBuffer() { return null; }
public virtual ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_END;
}
public virtual void DoBeforeDel()
{
}
public ActorBase()
{
}
virtual public Rect<int> rect
{
get { return m_rect; }
set { m_rect = value; }
}
virtual public int flag
{
get { return 0; }
}
virtual public bool hide
{
get { return m_hide; }
set
{
m_hide = value;
}
}
virtual public bool freeze
{
get { return m_freeze; }
set
{
m_freeze = value;
}
}
virtual public IActor parent
{
get { return m_parent; }
set { m_parent = value; }
}
/// <summary>
/// 物品所屬的層
/// </summary>
[XmlIgnore]
virtual public IActorLayerMng parentLayer
{
get { return m_parent_layer; }
set { m_parent_layer = value; }
}
IActorLayerMng m_parent_layer = null;
protected QuaternionF m_quat = QuaternionF.Identity;
virtual public string name
{
get { return ""; }
set { AssertUtil.confirm(this is PrefebActor); }
}
/// <summary>
/// 是否顯示名稱
/// </summary>
virtual public bool canDisplayName
{
get { return m_canDisplayName; }
set { m_canDisplayName = value; }
}
bool m_canDisplayName = true;
virtual public Matrix4F locationmat
{
get { return m_locationmat; }
set
{
m_locationmat = value;
updateLocationAABB();
}
}
virtual public Vector3F Scale
{
get
{
return m_scale;
}
}
protected Vector3F m_scale = new Vector3F(1, 1, 1);
// 獲得物品Memento
virtual public IMemento getMemento(int mode)
{
ActorMemento mem = new ActorMemento();
foreach (KeyValuePair<string, string> kv in m_property_dic)
{
mem.m_property_dic.Add(kv.Key, kv.Value);
}
return mem;
}
// 設定物品Memento
virtual public void setMemento(IMemento mem)
{
ActorMemento actormem = (ActorMemento)mem;
foreach (KeyValuePair<string, string> kv in actormem.m_property_dic)
{
notifyPropertyChange(kv.Key, kv.Value);
}
}
// 移動物品
virtual public void move(Vector3F v)
{
// // 移動Group中的子物品
// IActorLayerMng sublayer = getActorBuffer();
// if (sublayer != null)
// {
// foreach (IActor actor in sublayer.getOrgBuffer())
// {
// actor.move(v);
// }
// }
// else // 非Group物品
// {
// Matrix4F matrixmove = TransformationF.Translation(v);
// notifyPropertyChange("LocationMat", (matrixmove * locationmat).ToString());
// }
// 移動Group中的子物品
IActorLayerMng sublayer = getActorBuffer();
if (sublayer != null)
{
foreach (IActor actor in sublayer.getOrgBuffer())
{
actor.move(v);
}
}
Matrix4F matrixmove = TransformationF.Translation(v);
notifyPropertyChange("LocationMat", (matrixmove * locationmat).ToString());
}
virtual public void Attach(ClientBridge.SceneBase scene)
{
}
virtual public void Detach(ClientBridge.SceneBase scene)
{
}
virtual public void SetLod(ClientBridge.LOD_LEVEL lod)
{
}
// 将物品移動到某位置
virtual public void moveTo(Vector3F pos)
{
// // 移動Group中的子物品到某位置
// IActorLayerMng sublayer = getActorBuffer();
// if (sublayer != null)
// {
// foreach (IActor actor in sublayer.getOrgBuffer())
// {
// //Vector3F minpos = GActorHelper.getMinPos(sublayer.getOrgBuffer());
// //Vector3F possub = new Vector3F(pos.X + (actor.aabb.Min.X - minpos.X),
// // pos.Y + (actor.aabb.Min.Y - minpos.Y),
// // pos.Z + (actor.aabb.Min.Z - minpos.Z));
//
// Vector3F possub = new Vector3F(pos.X + (actor.locationmat.M14 - locationmat.M14),
// pos.Y + (actor.locationmat.M24 - locationmat.M24),
// pos.Z + (actor.locationmat.M34 - locationmat.M34));
// actor.moveTo(possub);
// }
// }
// //else // fixme:
// {
// Matrix4F matrixmove = TransformationF.Translation(pos);
// notifyPropertyChange("LocationMat", (matrixmove * Matrix4F.Identity).ToString());
// }
// 移動Group中的子物品到某位置
IActorLayerMng sublayer = getActorBuffer();
if (sublayer != null)
{
foreach (IActor actor in sublayer.getOrgBuffer())
{
//Vector3F minpos = GActorHelper.getMinPos(sublayer.getOrgBuffer());
//Vector3F possub = new Vector3F(pos.X + (actor.aabb.Min.X - minpos.X),
// pos.Y + (actor.aabb.Min.Y - minpos.Y),
// pos.Z + (actor.aabb.Min.Z - minpos.Z));
Vector3F possub = new Vector3F(pos.X + (actor.locationmat.M14 - locationmat.M14),
pos.Y + (actor.locationmat.M24 - locationmat.M24),
pos.Z + (actor.locationmat.M34 - locationmat.M34));
actor.moveTo(possub);
}
}
Matrix4F matrixmove = TransformationF.Translation(pos);
Matrix4F locatmat = new Matrix4F(locationmat);
locatmat.M14 = 0;
locatmat.M24 = 0;
locatmat.M34 = 0;
notifyPropertyChange("LocationMat", (matrixmove * locatmat).ToString());
}
virtual protected bool CanTransform()
{
return true;
}
public virtual void UpdateCpuSkin(float t)
{
}
virtual public void align(IActor dst_actor, bool x_axis, bool y_axis, bool z_axis)
{
if (CanTransform() && dst_actor != null)
{
Vector3F pos = new Vector3F((x_axis ? dst_actor.locationmat.M14 : locationmat.M14), (y_axis ? dst_actor.locationmat.M24 : locationmat.M24), (z_axis ? dst_actor.locationmat.M34 : locationmat.M34));
moveTo(pos);
}
}
private void set_world_location(Vector3F wloc)
{
Matrix4F matrixmove = TransformationF.Translation(wloc);
Matrix4F locatmat = new Matrix4F(locationmat);
locatmat.M14 = 0;
locatmat.M24 = 0;
locatmat.M34 = 0;
notifyPropertyChange("LocationMat", (matrixmove * locatmat).ToString());
}
// 旋轉物品
virtual public void rotate(Vector3F pos, Vector3F axis, float angle)
{
axis.Normalize();
QuaternionF quat = QuaternionF.FromAxisAngle(axis, angle);
m_quat = quat * m_quat;
m_quat.Normalize();
// Group
IActorLayerMng sublayer = getActorBuffer();
if (sublayer != null)
{
foreach (IActor actor in sublayer.getOrgBuffer())
{
Vector3F rotatecenter = pos;
GroupActor groupactor = actor.parent as GroupActor;
if (groupactor != null && groupactor.rotatemode == RotateMode.RM_SELF) // Group内物品繞自身軸旋轉
{
rotatecenter = actor.center;
}
actor.rotate(rotatecenter, axis, angle);
}
}
Matrix4F matrixmove = TransformationF.Translation(-pos);
Matrix4F matrixrotate = TransformationF.RotationAxis(axis, angle);
Matrix4F matrixmoveback = TransformationF.Translation(pos);
notifyPropertyChange("LocationMat", (matrixmoveback * matrixrotate * matrixmove * locationmat).ToString());
Vector3F euler = Tool.QuaternionToEulerXYZ(m_quat);
m_euler.X = Tool.Rad2Deg(euler.X);
m_euler.Y = Tool.Rad2Deg(euler.Y);
m_euler.Z = Tool.Rad2Deg(euler.Z);
notifyPropertyChange("旋轉角度", m_euler.ToString());
return;
}
// 縮放
private void scale(float x, float y, float z)
{
Vector3F center = new Vector3F(locationmat.M14, locationmat.M24, locationmat.M34);
Matrix4F matrixmove = TransformationF.Translation(-center);
Matrix4F matrixscale = TransformationF.Scaling(x, y, z);
Matrix4F matrixmoveback = TransformationF.Translation(center);
notifyPropertyChange("LocationMat", (matrixmoveback * matrixscale * matrixmove * locationmat).ToString());
}
// 縮放
virtual public void scaleForPar(Vector3F scale_var)
{
if (CanTransform())
{
Vector3F new_scale = new Vector3F(scale_var.X * m_scale.X, scale_var.Y * m_scale.Y, scale_var.Z * m_scale.Z);
notifyPropertyChange("縮放比例", new_scale.ToString());
}
}
virtual public void scale(Vector3F scale_var)
{
m_scale = new Vector3F(scale_var.X * m_scale.X, scale_var.Y * m_scale.Y, scale_var.Z * m_scale.Z);
Vector3F center = new Vector3F(locationmat.M14, locationmat.M24, locationmat.M34);
Matrix4F matrixmove = TransformationF.Translation(-center);
Matrix4F matrixscale = TransformationF.Scaling(scale_var.X, scale_var.Y, scale_var.Z);
Matrix4F matrixmoveback = TransformationF.Translation(center);
notifyPropertyChange("縮放比例", (matrixmoveback * matrixscale * matrixmove * locationmat).ToString());
}
private void rotate(Vector3F euler)
{
Vector3F r_euler = new Vector3F(Tool.Deg2Rad(euler.X), Tool.Deg2Rad(euler.Y), Tool.Deg2Rad(euler.Z));
m_quat = Tool.EulerXYZToQuaternion(r_euler);
m_quat.Normalize();
Matrix4F matrixscale = TransformationF.Scaling(m_scale);
Matrix4F matrixrotate = QuaternionF.QuaternionToMatrix(m_quat);
Matrix4F matrixmoveback = TransformationF.Translation(new Vector3F(locationmat.M14, locationmat.M24, locationmat.M34));
notifyPropertyChange("LocationMat", (matrixmoveback * matrixscale * matrixrotate).ToString());
}
virtual public AxisAlignedBox aabb
{
get { return m_aabb; }
set
{
m_aabb = value;
// 更新物品中心
//m_center = new Vector3F(locationmat.M14, locationmat.M24, locationmat.M34);
m_center = new Vector3F((m_aabb.Min.X + m_aabb.Max.X) / 2.0f, (m_aabb.Min.Y + m_aabb.Max.Y) / 2.0f, (m_aabb.Min.Z + m_aabb.Max.Z) / 2.0f);
}
}
virtual public Vector3F center
{
get { return m_center; }
set { m_center = value; }
}
virtual public void updateLocationAABB()
{
// 所有物品在更新位置時都需要更新其父物品的位置,放到基類
if (parent != null)
{
parent.updateLocationAABB();
}
}
public virtual void update(int t)
{
}
public virtual void render(int t, ClientBridge.ClientRenderSys rendersys)
{
}
// 繪制包圍盒
public virtual void renderAABB(int t, ClientBridge.ClientRenderSys rendersys, Color color)
{
float[] c = { color.r, color.g, color.b, color.a };
Vector3F[] vetexs = aabb.ComputeVertices();
float[] points = new float[24];
for (int i = 0; i < 8; i++)
{
points[i * 3] = vetexs[i].X;
points[i * 3 + 1] = vetexs[i].Y;
points[i * 3 + 2] = vetexs[i].Z;
}
int[] indexs = { 0,1, 1,2, 2,3, 3,0,
4,5, 5,6, 6,7, 7,4,
0,4, 1,5, 2,6, 3,7
};
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexs, c, false);
}
// 将移動控制軸加入到硬體選擇
virtual public void pushHardwareSelect_Move(ClientBridge.ClientRenderSys rendersys)
{
GroupActor ga = this as GroupActor;
if (ga != null && !ga.close)
{
ActorBuffer gab = getActorBuffer().getOrgBuffer();
foreach (IActor gasel in gab)
{
gasel.pushHardwareSelect_Move(rendersys);
}
}
float[] colorr = { 1, 0, 0, 1 };
float[] colorg = { 0, 1, 0, 1 };
float[] colorb = { 0, 0, 1, 1 };
float[] colorw = { 1, 1, 1, 1 };
float[] points = { center.X, center.Y, center.Z, // 0 o
center.X + 2.0f, center.Y, center.Z, // 1 x
center.X, center.Y + 2.0f, center.Z, // 2 y
center.X, center.Y,center.Z + 2.0f, // 3 z
center.X + 1.0f, center.Y, center.Z, // 4 x_h
center.X, center.Y +1.0f, center.Z, // 5 y_h
center.X, center.Y, center.Z + 1.0f, // 6 z_h
center.X+1.0f, center.Y+1.0f, center.Z, // 7 x_y
center.X+1.0f, center.Y, center.Z + 1.0f, // 8 x_z
center.X, center.Y+1.0f, center.Z + 1.0f // 9 y_z
};
int[] indexs_x = { 0, 1 }; // x軸索引
int[] indexs_y = { 0, 2 }; // y軸索引
int[] indexs_z = { 0, 3 }; // z軸索引
int[] indexs_xy = { 4, 7, 5 }; // xy夾角索引
int[] indexs_xz = { 4, 8, 6 }; // xz夾角索引
int[] indexs_yz = { 5, 9, 6 }; // yz夾角索引
rendersys.pushSelectID((uint)(m_move_giid[0].value));
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_x, colorr, true);
rendersys.pushSelectID((uint)(m_move_giid[1].value));
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_y, colorg, true);
rendersys.pushSelectID((uint)(m_move_giid[2].value));
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_z, colorb, true);
rendersys.pushSelectID((uint)(m_move_giid[3].value));
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_xy, colorw, true);
rendersys.pushSelectID((uint)(m_move_giid[4].value));
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_xz, colorw, true);
rendersys.pushSelectID((uint)(m_move_giid[5].value));
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_yz, colorw, true);
return;
}
// 繪制移動控制軸
public virtual void renderCoordinate(int t, ClientBridge.ClientRenderSys rendersys)
{
float[] colorr = { 1, 0, 0, 1 };
float[] colorg = { 0, 1, 0, 1 };
float[] colorb = { 0, 0, 1, 1 };
float[] colorw = { 1, 1, 1, 1 };
float[] points = { center.X, center.Y, center.Z, // 0 o
center.X + 2.0f, center.Y, center.Z, // 1 x
center.X, center.Y + 2.0f, center.Z, // 2 y
center.X, center.Y,center.Z + 2.0f, // 3 z
center.X + 1.0f, center.Y, center.Z, // 4 x_h
center.X, center.Y +1.0f, center.Z, // 5 y_h
center.X, center.Y, center.Z + 1.0f, // 6 z_h
center.X+1.0f, center.Y+1.0f, center.Z, // 7 x_y
center.X+1.0f, center.Y, center.Z + 1.0f, // 8 x_z
center.X, center.Y+1.0f, center.Z + 1.0f // 9 y_z
};
int[] indexs_x = { 0, 1 }; // x軸索引
int[] indexs_y = { 0, 2 }; // y軸索引
int[] indexs_z = { 0, 3 }; // z軸索引
int[] indexs_xy = { 4, 7, 5 }; // xy夾角索引
int[] indexs_xz = { 4, 8, 6 }; // xz夾角索引
int[] indexs_yz = { 5, 9, 6 }; // yz夾角索引
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_x, colorr, true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_y, colorg, true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_z, colorb, true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_xy, colorw, true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_xz, colorw, true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_yz, colorw, true);
}
// 将移動控制軸加入到硬體選擇
virtual public void pushHardwareSelect_Rotate(ClientBridge.ClientRenderSys rendersys)
{
GroupActor ga = this as GroupActor;
if (ga != null && !ga.close)
{
ActorBuffer gab = getActorBuffer().getOrgBuffer();
foreach (IActor gasel in gab)
{
gasel.pushHardwareSelect_Rotate(rendersys);
}
}
List<uint> idlist = new List<uint>();
for (int i = 0; i < m_rotate_giid.Count; i++)
{
idlist.Add((uint)m_rotate_giid[i].value);
}
GActorHelper.drawRotateCircles(idlist, center, rendersys);
return;
}
// 繪制旋轉控制圓
public virtual void renderCircles(int t, ClientBridge.ClientRenderSys rendersys)
{
GActorHelper.drawRotateCircles(null, center, rendersys);
}
/// <summary>
/// Xml序列化使用
/// </summary>
public Vector3F Euler
{
get { return m_euler; }
}
protected Vector3F m_euler = new Vector3F(0, 0, 0);
public Vector3F Trans
{
get { return m_trans; }
}
protected Vector3F m_trans = new Vector3F(0, 0, 0);
/// <summary>
/// 是否産生實時陰影
/// </summary>
virtual public bool castshadow
{
get { return m_castshadow; }
set { m_castshadow = value; }
}
bool m_castshadow = true;
/// <summary>
/// 是否物體生成陰影
/// </summary>
virtual public bool genlightmap
{
get { return m_genLightMap; }
set { m_genLightMap = value; }
}
bool m_genLightMap = true;
public GIID giid
{
get { return m_giid; }
private set { m_giid = value; }
}
public List<GIID> giid_move
{
get { return m_move_giid; }
}
public List<GIID> giid_rotate
{
get { return m_rotate_giid; }
}
// 得到物品屬性清單
virtual public IDictionary<String, String> getPropertyList()
{
return m_property_dic;
}
virtual public void notifyPropertyChange(String key, String value)
{
string old_value = m_property_dic.ContainsKey(key) ? m_property_dic[key] : null;
m_property_dic[key] = value;
if (key == "LocationMat")
{
locationmat = Matrix4F.setMatrix(value);
}
else if (key == "Hide")
{
hide = bool.Parse(value);
}
else if (key == "Freeze")
{
freeze = bool.Parse(value);
}
else if (key == "産生陰影")
{
if (!bool.TryParse(value, out m_genLightMap))
{
return;
}
}
else if (key == "實時陰影")
{
if (!bool.TryParse(value, out m_castshadow))
{
return;
}
}
else if (key == "縮放比例")
{
Vector3F old_scale, new_scale;
try
{
old_scale = Vector3F.Parse(old_value);
new_scale = Vector3F.Parse(value);
}
catch
{
return;
}
if (old_scale.X != 0 && old_scale.Y != 0 && old_scale.Z != 0)
{
m_scale = new_scale;
scale(new_scale.X / old_scale.X, new_scale.Y / old_scale.Y, new_scale.Z / old_scale.Z);
}
}
else if (key == "世界坐标")
{
try
{
m_trans = Vector3F.Parse(value);
}
catch (System.Exception)
{
return;
}
set_world_location(m_trans);
}
else if (key == "旋轉角度")
{
Vector3F euler = new Vector3F(0, 0, 0);
try { euler = Vector3F.Parse(value); }
catch (System.Exception) { return; }
if (!Tool.FloatCompare(euler.X, m_euler.X, 0.001f) ||
!Tool.FloatCompare(euler.Y, m_euler.Y, 0.001f) ||
!Tool.FloatCompare(euler.Z, m_euler.Z, 0.001f))
{
m_euler = euler;
rotate(m_euler);
}
}
insertValueToPropertyDic(key, value);
}
public virtual void insertValueToPropertyDic(string key, string value)
{
m_property_dic[key] = value;
}
public ActorBase(GIIDMng giidmng)
{
m_giid = giidmng.getGIID();
for (int i = 0; i < 6; i++)
{
m_move_giid.Add(giidmng.getGIID());
}
for (int i = 0; i < 3; i++)
{
m_rotate_giid.Add(giidmng.getGIID());
}
m_property_dic["Hide"] = hide.ToString();
m_property_dic["Freeze"] = freeze.ToString();
m_property_dic["産生陰影"] = m_genLightMap.ToString();
m_property_dic["實時陰影"] = m_castshadow.ToString();
m_property_dic["縮放比例"] = m_scale.ToString();
m_property_dic["世界坐标"] = m_trans.ToString();
m_property_dic["旋轉角度"] = m_euler.ToString();
}
public bool serialize(IFile file, IEditItem edititem, bool load)
{
return true;
}
// 儲存讀取
public virtual bool serialize(System.Xml.XmlNode xmlnode, IEditItem edititem, bool load, bool clipboard)
{
if (load)
{
foreach (XmlNode childnode in xmlnode.ChildNodes)
{
if (childnode.Name != "Item")
{
m_property_dic[childnode.Name] = childnode.Value;
notifyPropertyChange(childnode.Name, childnode.InnerText);
}
else
{ //
IActor actor = GActorHelper.generateActorWithoutInfo(childnode.Attributes["type"].Value, edititem);
actor.serialize(childnode, edititem, load, clipboard);
getActorBuffer().getOrgBuffer().insert(actor);
}
}
}
else // save
{
foreach (KeyValuePair<string, string> kv in m_property_dic)
{
XmlNode node = xmlnode.OwnerDocument.CreateNode("element", kv.Key, "");
node.InnerText = kv.Value;
xmlnode.InsertAfter(node, xmlnode.LastChild);
}
if (this is GroupActor)
{
foreach (IActor subactor in getActorBuffer().getOrgBuffer())
{
XmlNode node = xmlnode.OwnerDocument.CreateNode("element", "Item", "");
XmlAttribute att = xmlnode.OwnerDocument.CreateAttribute("type");
att.Value = GActorHelper.getActorTypestr(subactor);
node.Attributes.Append(att);
subactor.serialize(node, edititem, load, clipboard);
xmlnode.InsertAfter(node, xmlnode.LastChild);
}
}
}
return true;
}
// 儲存物品
virtual public bool serialize(BinaryWriter binWriter)
{
binWriter.Write(hide);
binWriter.Write(freeze);
for (int i = 0; i < 16; i++)
{
binWriter.Write(locationmat[i]);
}
return true;
}
// 讀取物品
virtual public bool serialize(BinaryReader binReader, IEditItem edititem)
{
notifyPropertyChange("Hide", binReader.ReadBoolean().ToString());
notifyPropertyChange("Freeze", binReader.ReadBoolean().ToString());
float[] locarray = new float[16];
for (int i = 0; i < 16; i++)
{
locarray[i] = binReader.ReadSingle();
}
// 恢複儲存到二進制檔案的Prefeb執行個體的位置
if (this is PrefebActor)
{
Vector3F pos = new Vector3F(locarray[3], locarray[7], locarray[11]);
Vector3F posold = GActorHelper.getMinPos(getActorBuffer().getOrgBuffer());
foreach (IActor subactor in getActorBuffer().getOrgBuffer())
{
subactor.move(pos - posold);
}
}
notifyPropertyChange("LocationMat", (new Matrix4F(locarray)).ToString());
return true;
}
virtual public void pushHardwareSelect(ClientBridge.ClientRenderSys rendersys)
{
return;
}
public virtual void pushLineHardwareSelect(ClientBridge.ClientRenderSys rendersys)
{
return;
}
// 擷取物體是否可見
public virtual bool isVisible()
{
return !(hide || BaseCommand.isActorLayerReadOnly(parentLayer, BaseCommand.ACTORLAYER_ITERATE_MODE.HIDE));
}
public virtual bool mouseHover(Rect<int> rect, IView view)
{
return true;
}
public virtual bool mouseSelect(Rect<int> rect, IView view)
{
return true;
}
// 得到物品類别字元串
virtual public string getActorTypestr()
{
return "Actor";
}
//父物品層Hide操作回調
virtual public void notifyLayerHide(bool isHide)
{
if (!hide && getActorBuffer() != null)
getActorBuffer().notifyLayerHide(isHide);
}
//父物品層Freeze操作回調
virtual public void notifyLayerFreeze(bool isFreeze)
{
if (!freeze && getActorBuffer() != null)
getActorBuffer().notifyLayerFreeze(isFreeze);
}
public virtual System.Xml.Schema.XmlSchema GetSchema()
{
throw new NotImplementedException();
}
public virtual void ReadXmlInner(System.Xml.XmlReader reader)
{
this.giid = (GIID)Serializer.ReadXmlObj(reader, "giid");
this.hide = (bool)Serializer.ReadXmlObj(reader, "hide");
this.freeze = (bool)Serializer.ReadXmlObj(reader, "freeze");
SDictionary<string, string> temp
= (SDictionary<String, String>)Serializer.ReadXmlObj(reader, "m_property_dic");
this.m_property_dic = SDictionary<string, string>.ToDic(temp);
this.locationmat = (Matrix4F)Serializer.ReadXmlObj(reader, "locationmat");
this.aabb = (AxisAlignedBox)Serializer.ReadXmlObj(reader, "aabb");
this.center = (Vector3F)Serializer.ReadXmlObj(reader, "center");
this.genlightmap = (bool)Serializer.ReadXmlObj(reader, "genlightmap");
this.castshadow = (bool)Serializer.ReadXmlObj(reader, "castshadow");
this.m_scale = (Vector3F)Serializer.ReadXmlObj(reader, "m_scale");
this.m_trans = (Vector3F)Serializer.ReadXmlObj(reader, "m_trans");
this.m_euler = (Vector3F)Serializer.ReadXmlObj(reader, "m_euler");
}
public virtual void ReadXml(XmlReader reader)
{
Serializer.PreReadXmlObj(reader);
ReadXmlInner(reader);
Serializer.AfterReadXmlObj(reader);
}
public virtual void WriteXml(XmlWriter writer)
{
Serializer.WriteXmlObj(writer, this.giid, "giid");
Serializer.WriteXmlObj(writer, this.hide, "hide");
Serializer.WriteXmlObj(writer, this.freeze, "freeze");
SDictionary<string, string> temp = SDictionary<string, string>.ToSDic(m_property_dic);
Serializer.WriteXmlObj(writer, temp, "m_property_dic");
Serializer.WriteXmlObj(writer, this.locationmat, "locationmat");
Serializer.WriteXmlObj(writer, this.aabb, "aabb");
Serializer.WriteXmlObj(writer, this.center, "center");
Serializer.WriteXmlObj(writer, this.genlightmap, "genlightmap");
Serializer.WriteXmlObj(writer, this.castshadow, "castshadow");
Serializer.WriteXmlObj(writer, this.m_scale, "m_scale");
Serializer.WriteXmlObj(writer, this.m_trans, "m_trans");
Serializer.WriteXmlObj(writer, this.m_euler, "m_euler");
}
}
public enum DETAIL_ACTOR_TYPE
{
DAT_HUGE_ACTOR,
DAT_SMALL_ACTOR,
DAT_DETAIL_VEGETATION,
}
// 模型資訊
public class ModelActorInfo
{
public string m_model_name; // 物品名稱 字首+id
public string m_resouce_name; // 資源名成
public float m_height; // 距離地面高度
public bool m_collide;
public bool m_is_bridge;
public bool m_visible_ingame;
public float m_visible_distance; // 可見範圍
public bool m_far_object; // 遠處的對象
public bool m_is_tree;
public bool m_temp_transparent;
public bool m_reflection;
public bool m_lightable = false; //是否接受光斑
public bool m_use_lightmap = true; //是否應用Lightmap
//public bool m_selshadow_in_lightmap = false; //Ligthmap中是否有自陰影
public string m_lightmap_quality = "普通"; //Lightmap品質
public DETAIL_ACTOR_TYPE m_dat = DETAIL_ACTOR_TYPE.DAT_SMALL_ACTOR; // 細節物體類型
public bool m_as_actor; // 是否受角色光
public ModelActorInfo(Dictionary<string, string> createpropdic, int curindex)
{
string nameprefix = "M_" + createpropdic["NamePrefix"];
m_model_name = nameprefix + "_" + curindex.ToString();
m_resouce_name = createpropdic["ResName"];
try
{
m_height = float.Parse(createpropdic["Height"]);
}
catch (Exception)
{
m_height = 0;
}
m_collide = false;
m_is_bridge = false;
m_visible_ingame = true;
m_far_object = false;
m_is_tree = false;
m_temp_transparent = true;
m_lightable = false;
m_use_lightmap = true;
//m_selshadow_in_lightmap = false;
m_lightmap_quality = "普通";
m_as_actor = false;
if (createpropdic.ContainsKey("碰撞物體"))
{
m_collide = createpropdic["碰撞物體"].ToLower() == "true";
}
if (createpropdic.ContainsKey("橋梁物體"))
{
m_is_bridge = createpropdic["橋梁物體"].ToLower() == "true";
}
if (createpropdic.ContainsKey("遊戲中可見"))
{
m_visible_ingame = createpropdic["遊戲中可見"].ToLower() == "true";
}
if (createpropdic.ContainsKey("可視距離"))
{
if (!float.TryParse(createpropdic["可視距離"], out m_visible_distance))
{
m_visible_distance = 1000;
}
}
else
{
m_visible_distance = 1000;
}
if (createpropdic.ContainsKey("遠景"))
{
m_far_object = createpropdic["遠景"].ToLower() == "true";
}
if (createpropdic.ContainsKey("是否是樹"))
{
m_is_tree = createpropdic["是否是樹"].ToLower() == "true";
}
if (createpropdic.ContainsKey("臨時透明"))
{
m_temp_transparent = createpropdic["臨時透明"].ToLower() == "true";
}
m_reflection = true;
if (createpropdic.ContainsKey("反射中繪制"))
{
bool.TryParse(createpropdic["反射中繪制"], out m_reflection);
}
if (createpropdic.ContainsKey("是否接受光斑"))
{
m_lightable = createpropdic["是否接受光斑"].ToLower() == "true";
}
if (createpropdic.ContainsKey("是否應用Lightmap"))
{
m_use_lightmap = createpropdic["是否應用Lightmap"].ToLower() == "true";
}
//if (createpropdic.ContainsKey("Ligthmap中是否有自陰影"))
//{
// m_selshadow_in_lightmap = createpropdic["Ligthmap中是否有自陰影"].ToLower() == "true";
//}
if (createpropdic.ContainsKey("Lightmap品質"))
{
m_lightmap_quality = createpropdic["Lightmap品質"];
}
if (createpropdic.ContainsKey("細節物體類型"))
{
m_dat = (DETAIL_ACTOR_TYPE)Enum.Parse(typeof(DETAIL_ACTOR_TYPE), createpropdic["細節物體類型"], true);
}
if (createpropdic.ContainsKey("受角色光"))
{
bool.TryParse(createpropdic["受角色光"], out m_as_actor);
}
}
public ModelActorInfo(string modelname, string resname, float height)
{
m_model_name = modelname;
m_resouce_name = resname;
m_height = height;
}
public ModelActorInfo(string modelname, string resname, float height, bool collide, bool is_bridge, bool visible_ingame, float visible_distance, bool far_object, bool is_tree, bool temp_transparent, bool reflection)
{
m_model_name = modelname;
m_resouce_name = resname;
m_height = height;
m_collide = collide;
m_is_bridge = is_bridge;
m_visible_ingame = visible_ingame;
m_visible_distance = visible_distance;
m_far_object = far_object;
m_is_tree = is_tree;
m_temp_transparent = temp_transparent;
m_reflection = reflection;
m_lightable = false;
m_use_lightmap = true;
//m_selshadow_in_lightmap = false;
m_lightmap_quality = "普通";
m_dat = DETAIL_ACTOR_TYPE.DAT_SMALL_ACTOR;
m_as_actor = false;
}
// 轉換成屬性清單
public void toDic(Dictionary<string, string> dic)
{
dic["Name"] = m_model_name;
dic["ResName"] = m_resouce_name;
dic["Height"] = m_height.ToString();
dic["碰撞物體"] = m_collide.ToString();
dic["橋梁物體"] = m_is_bridge.ToString();
dic["遊戲中可見"] = m_visible_ingame.ToString();
//dic["可視距離"] = m_visible_distance.ToString();
dic["遠景"] = m_far_object.ToString();
dic["是否是樹"] = m_is_tree.ToString();
dic["臨時透明"] = m_temp_transparent.ToString();
dic["反射中繪制"] = m_reflection.ToString();
dic["是否接受光斑"] = m_lightable.ToString();
dic["是否應用Lightmap"] = m_use_lightmap.ToString();
//dic["Ligthmap中是否有自陰影"] = m_selshadow_in_lightmap.ToString();
dic["Lightmap品質"] = m_lightmap_quality;
dic["受角色光"] = m_as_actor.ToString();
string dat;
if (m_dat == DETAIL_ACTOR_TYPE.DAT_DETAIL_VEGETATION)
dat = "細節植被";
else if (m_dat == DETAIL_ACTOR_TYPE.DAT_HUGE_ACTOR)
dat = "大型物體";
else
dat = "小型物體";
dic["細節物體類型"] = dat;
}
public ModelActorInfo()
{
}
// 轉換成存儲清單
public void toDicAll(Dictionary<string, string> dic)
{
dic["Name"] = m_model_name;
dic["ResName"] = m_resouce_name;
dic["Height"] = m_height.ToString();
dic["碰撞物體"] = m_collide.ToString();
dic["橋梁物體"] = m_is_bridge.ToString();
dic["遊戲中可見"] = m_visible_ingame.ToString();
dic["可視距離"] = m_visible_distance.ToString();
dic["遠景"] = m_far_object.ToString();
dic["是否是樹"] = m_is_tree.ToString();
dic["臨時透明"] = m_temp_transparent.ToString();
dic["反射中繪制"] = m_reflection.ToString();
dic["是否接受光斑"] = m_lightable.ToString();
dic["是否應用Lightmap"] = m_use_lightmap.ToString();
//dic["Ligthmap中是否有自陰影"] = m_selshadow_in_lightmap.ToString();
dic["Lightmap品質"] = m_lightmap_quality;
dic["細節物體類型"] = m_dat.ToString();
dic["受角色光"] = m_as_actor.ToString();
}
public int getLightmapQualityPower(string value)
{
switch (value)
{
case "最低":
return -2;
case "低":
return -1;
case "普通":
return 0;
case "高":
return 1;
case "最高":
return 2;
default:
return int.MaxValue;
}
}
// 更新屬性值
public void valueChanged(string key, string value)
{
switch (key)
{
case "Name":
m_model_name = value;
break;
case "ResName":
m_resouce_name = value;
break;
case "Height":
try
{
m_height = float.Parse(value);
}
catch (Exception)
{
m_height = 0;
}
break;
case "碰撞物體":
m_collide = value.ToLower() == "true";
break;
case "橋梁物體":
m_is_bridge = value.ToLower() == "true";
break;
case "遊戲中可見":
m_visible_ingame = value.ToLower() == "true";
break;
case "可視距離":
float.TryParse(value, out m_visible_distance);
break;
case "遠景":
m_far_object = value.ToLower() == "true";
break;
case "是否是樹":
m_is_tree = value.ToLower() == "true";
break;
case "臨時透明":
m_temp_transparent = value.ToLower() == "true";
break;
case "反射中繪制":
bool.TryParse(value, out m_reflection);
break;
case "是否接受光斑":
m_lightable = value.ToLower() == "true";
break;
case "是否應用Lightmap":
m_use_lightmap = value.ToLower() == "true";
break;
//case "Ligthmap中是否有自陰影":
// m_selshadow_in_lightmap = value.ToLower() == "true";
// break;
case "Lightmap品質":
m_lightmap_quality = value;
break;
case "細節物體類型":
if (value == "大型物體" || value == DETAIL_ACTOR_TYPE.DAT_HUGE_ACTOR.ToString())
m_dat = DETAIL_ACTOR_TYPE.DAT_HUGE_ACTOR;
if (value == "小型物體" || value == DETAIL_ACTOR_TYPE.DAT_SMALL_ACTOR.ToString())
m_dat = DETAIL_ACTOR_TYPE.DAT_SMALL_ACTOR;
if (value == "細節植被" || value == DETAIL_ACTOR_TYPE.DAT_DETAIL_VEGETATION.ToString())
m_dat = DETAIL_ACTOR_TYPE.DAT_DETAIL_VEGETATION;
break;
case "受角色光":
bool.TryParse(value, out m_as_actor);
break;
default:
break;
}
}
}
// 模型
public class ModelActor : ResActorBase, IActor
{
public ModelActor(GIIDMng giidmng, Dictionary<string, string> createpropdic, ClientBridge.ClientRenderSys rendersys, int curindex)
: base(giidmng)
{
m_actor_info = new ModelActorInfo(createpropdic, curindex);
m_model = rendersys.createModel(m_actor_info.m_resouce_name);
if (m_model == null)
{
return;
}
//m_model.setVisibleDist(visible_distance);
notifyPropertyChange("實時陰影", "True");
//notifyPropertyChange("是否是樹", "False");
//notifyPropertyChange("臨時透明", "True");
return;
}
public ModelActor(GIIDMng giidmng)
: base(giidmng)
{
m_actor_info = new ModelActorInfo();
if (m_model != null)
notifyPropertyChange("實時陰影", "True");
//notifyPropertyChange("是否是樹", "False");
//notifyPropertyChange("臨時透明", "True");
//notifyPropertyChange("反射中繪制", "True");
return;
}
override public void Attach(ClientBridge.SceneBase scene)
{
if (m_model != null)
{
m_model.Attach(scene);
}
}
override public void Detach(ClientBridge.SceneBase scene)
{
if (m_model != null)
{
m_model.Detach(scene);
}
}
override public void SetLod(ClientBridge.LOD_LEVEL lod)
{
if (m_model != null)
{
//m_model.setMaterialLod(lod);
}
}
override public bool hide
{
get { return base.hide; }
set
{
base.hide = value;
//父層為Hide,隻設定辨別位,否則進行具體Hide操作
if (m_model != null && !BaseCommand.isActorLayerReadOnly(parentLayer, BaseCommand.ACTORLAYER_ITERATE_MODE.HIDE))
{
//m_model.setVisible(!value);
}
}
}
public override void notifyLayerFreeze(bool isFreeze)
{
//base.notifyLayerFreeze(isFreeze);
}
//父物品層設定Hide通知
public override void notifyLayerHide(bool isHide)
{
if (hide)
return;
//if(m_model != null)
// m_model.setVisible(!isHide);
}
public override string name
{
get
{
return m_actor_info.m_model_name;
}
set
{
m_actor_info.m_model_name = value;
}
}
public string res
{
get
{
return m_actor_info.m_resouce_name;
}
}
public bool collide
{
get
{
return m_actor_info.m_collide;
}
}
public bool is_bridge
{
get
{
return m_actor_info.m_is_bridge;
}
}
public bool visible_ingame
{
get
{
return m_actor_info.m_visible_ingame;
}
}
public float visible_distance
{
get
{
return m_actor_info.m_visible_distance;
}
}
public bool far_object
{
get
{
return m_actor_info.m_far_object;
}
}
public bool is_tree
{
get
{
return m_actor_info.m_is_tree;
}
}
public bool temp_transparent
{
get
{
return m_actor_info.m_temp_transparent;
}
}
#region about IDisposable
virtual public void Dispose()
{
m_model.release();
}
#endregion
#region about IActor
// fixme : 各類物品的Clone目前都還沒有實作
public IActor clone(IEditItem edititem)
{
RootEditItem root = (RootEditItem)SceneGraph.getEditItemCommon("RootItem", edititem);
ModelActor actor = null;
return actor;
}
new public IMemento getMemento(int mode)
{
return null;
}
new public void setMemento(IMemento mem)
{
}
public override bool serialize(BinaryWriter binWriter)
{
binWriter.Write(m_actor_info.m_model_name);
binWriter.Write(m_actor_info.m_resouce_name);
binWriter.Write(m_actor_info.m_height);
return base.serialize(binWriter);
}
public override bool serialize(BinaryReader binReader, IEditItem edititem)
{
m_actor_info.m_model_name = binReader.ReadString();
m_actor_info.m_resouce_name = binReader.ReadString();
m_actor_info.m_height = binReader.ReadSingle();
RootEditItem root = (RootEditItem)(SceneGraph.getEditItemCommon("RootItem", edititem));
m_model = root.clientRenderSys.createModel(m_actor_info.m_resouce_name);
return base.serialize(binReader, edititem);
}
public override bool serialize(System.Xml.XmlNode xmlnode, IEditItem edititem, bool load, bool clipboard)
{
base.serialize(xmlnode, edititem, load, clipboard);
if (load)
{
RootEditItem root = (RootEditItem)(SceneGraph.getEditItemCommon("RootItem", edititem));
m_model = root.clientRenderSys.createModel(m_actor_info.m_resouce_name);
}
updateLocationAABB();
return true;
}
public override void render(int t, ClientBridge.ClientRenderSys rendersys)
{
// 調用自己的繪制函數
m_model.render();
}
public override void renderAABB(int t, ClientBridge.ClientRenderSys rendersys, Color color)
{
base.renderAABB(t, rendersys, color);
}
#endregion
public override IDictionary<string, string> getPropertyList()
{
m_actor_info.toDic(m_property_dic);
return base.getPropertyList();
}
public override void updateLocationAABB()
{
if (m_model == null)
{
return;
}
// 設定mat
List<float> matrix = new List<float>();
for (int i = 0; i < 16; i++)
{
matrix.Add(locationmat[i]);
}
m_model.setLocationMatrix(matrix);
// 修改包圍盒
List<float> aabblist = new List<float>();
for (int i = 0; i < 6; i++)
{
aabblist.Add(0);
}
m_model.getAABB(aabblist);
aabb = new AxisAlignedBox(new Vector3F(aabblist[0], aabblist[1], aabblist[2]),
new Vector3F(aabblist[3], aabblist[4], aabblist[5]));
base.updateLocationAABB();
}
public override void pushHardwareSelect(ClientBridge.ClientRenderSys rendersys)
{
rendersys.pushHardwareSelectObject(m_model, (uint)giid.value);
}
public override void notifyPropertyChange(String key, String value)
{
if (key == "Lightmap品質")
{
int cur_p = m_actor_info.getLightmapQualityPower(m_actor_info.m_lightmap_quality);
int new_p = m_actor_info.getLightmapQualityPower(value);
if (new_p == int.MaxValue)
{
return;
}
//if (!m_model.setLightmapQuality(new_p))
//{
// if (new_p > cur_p)
// {
// MessageBox.Show("不允許再提升品質");
// }
// else if (new_p < cur_p)
// {
// MessageBox.Show("不允許再降低品質");
// }
// return;
//}
}
if (key != "可視距離")
base.notifyPropertyChange(key, value);
m_actor_info.valueChanged(key, value);
if (m_model != null)
{
if (key == "可視距離")
{
//m_model.setVisibleDist(visible_distance);
}
else if (key == "實時陰影")
{
//m_model.setCastShadow(base.castshadow);
}
else if (key == "反射中繪制")
{
//m_model.setReflection(m_actor_info.m_reflection);
}
else if (key == "是否接受光斑")
{
//m_model.setLightable(m_actor_info.m_lightable);
}
else if (key == "受角色光")
{
//m_model.asActor(m_actor_info.m_as_actor);
}
}
}
public override string getActorTypestr()
{
return "模型";
}
public override ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_DML;
}
public ModelActorInfo m_actor_info;
public ClientBridge.Model m_model;
override public string ResName
{
get { return res; }
}
override public object getRes()
{
return m_model;
}
public override void changeRes(ClientBridge.ClientRenderSys rendersys, string new_res)
{
if (m_model != null)
{
m_model.changeRes(rendersys, new_res);
m_actor_info.m_resouce_name = new_res;
updateLocationAABB();
}
}
override public void addRef()
{
if (m_model != null)
{
m_model.addRef();
}
}
override public int ResRefCount
{
get
{
if (m_model != null)
{
return m_model.m_ref_count;
}
else
{
return 0;
}
}
}
}
// 骨骼模型
public class SkeletonModelActor : ActorBase, IActor
{
public SkeletonModelActor(GIIDMng giidmng, Dictionary<string, string> createpropdic, ClientBridge.ClientRenderSys rendersys, int curindex)
: base(giidmng)
{
m_actor_info = new ModelActorInfo(createpropdic, curindex);
m_model = rendersys.creatSkeletonModel(m_actor_info.m_resouce_name);
//m_model.setVisibleDist(visible_distance);
return;
}
public SkeletonModelActor(GIIDMng giidmng)
: base(giidmng)
{
m_actor_info = new ModelActorInfo();
return;
}
public override ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_CHR;
}
override public bool hide
{
get { return base.hide; }
set
{
base.hide = value;
}
}
public override string name
{
get
{
return m_actor_info.m_model_name;
}
}
public string res
{
get
{
return m_actor_info.m_resouce_name;
}
}
virtual public void Dispose()
{
if (m_model != null)
{
m_model.release();
}
}
#region about IActor
// fixme : 各類物品的Clone目前都還沒有實作
public IActor clone(IEditItem edititem)
{
RootEditItem root = (RootEditItem)SceneGraph.getEditItemCommon("RootItem", edititem);
ModelActor actor = null;
return actor;
}
protected void getSaveProperty(Dictionary<string, string> mPro)
{
foreach (KeyValuePair<string, string> kv in base.getPropertyList())
{
mPro[kv.Key] = kv.Value;
}
}
public override void update(int t)
{
if (hide == false)
{
m_model.update(((float)t) / 1.0f);
}
}
public override void render(int t, ClientBridge.ClientRenderSys rendersys)
{
if (!hide)
{
m_model.render();
}
}
public override void renderAABB(int t, ClientBridge.ClientRenderSys rendersys, Color color)
{
base.renderAABB(t, rendersys, color);
}
#endregion
public override IDictionary<string, string> getPropertyList()
{
m_actor_info.toDic(m_property_dic);
return base.getPropertyList();
}
public void updateAABB()
{
// 修改包圍盒
List<float> aabblist = new List<float>();
for (int i = 0; i < 6; i++)
{
aabblist.Add(0);
}
m_model.getAABB(aabblist);
aabb = new AxisAlignedBox(new Vector3F(aabblist[0], aabblist[1], aabblist[2]),
new Vector3F(aabblist[3], aabblist[4], aabblist[5]));
}
public override void updateLocationAABB()
{
if (m_model == null)
{
return;
}
// 設定mat
List<float> matrix = new List<float>();
for (int i = 0; i < 16; i++)
{
matrix.Add(locationmat[i]);
}
m_model.setLocationMatrix(matrix);
updateAABB();
}
public override void pushHardwareSelect(ClientBridge.ClientRenderSys rendersys)
{
rendersys.pushHardwareSelectObject(m_model, (uint)giid.value);
}
public override void notifyPropertyChange(String key, String value)
{
base.notifyPropertyChange(key, value);
m_actor_info.valueChanged(key, value);
}
public ModelActorInfo m_actor_info;
public ClientBridge.SkeletonModel m_model;
public void SetAction(int trackid, string actionname)
{
m_model.setAim(trackid, actionname);
}
public void SetActionTime(int trackid, float time)
{
m_model.SetCurrentActionTime(trackid, time);
}
public void PlayAction(int trackid, float time)
{
m_model.SetCurrentActionTime(trackid, time);
// m_model.update(0);
// m_irender.updatePhx((int)(0));//time*1000f
}
public void ClearChannelAnim(int id)
{
m_model.ClearChannelAnim(0);
}
public Vector3F GetPosFromRootBone()
{
if (m_model!=null)
{
string rootName = m_model.GetRootBoneName();
int rootID = m_model.GetBoneID(rootName);
List<float> mat = m_model.GetBoneLocation(rootID);
return new Vector3F(mat[3],mat[7],mat[11]);
}
return new Vector3F(0.0f,0.0f,0.0f);
}
}
// 角色
public class StageRoleActor : SkeletonModelActor
{
public StageRoleActor(GIIDMng giidmng, Dictionary<string, string> createpropdic, ClientBridge.ClientRenderSys rendersys, int curindex, bool male)
: base(giidmng)
{
m_crs = rendersys;
m_actor_info = new ModelActorInfo(createpropdic, curindex);
m_actor_model = m_crs.creatActorModel("StageRoleActor" + curindex.ToString(), male);
base.m_model = (ClientBridge.SkeletonModel)m_actor_model;
notifyPropertyChange("産生陰影", "True");
notifyPropertyChange("Update", "True");
return;
}
public override void update(int t)
{
base.update(t);
updateAABB();
}
public void SetBodyPart(int pos, string bpt_filename)
{
m_actor_model.SetBodyPart(pos, bpt_filename);
}
public void SetAdornment(ClientBridge.SpecialEffectMng sem, int pos, string lik_filename)
{
m_actor_model.SetAdornment(sem, pos, lik_filename);
}
public void PostProcessCreating()
{
m_actor_model.PostProcessCreating();
}
public override int flag
{
get { return (int)ActorFlag.UNDELETEABLE | (int)ActorFlag.UNSERIALIZABLE; }
}
public override void notifyPropertyChange(string key, string value)
{
if (key != "ResName")
{
base.notifyPropertyChange(key, value);
}
}
private ClientBridge.ClientRenderSys m_crs;
private ClientBridge.ActorModel m_actor_model;
}
// 特效資訊
public struct EffectActorInfo
{
public string m_effect_name; // 物品名稱 字首+id
public string m_resouce_name;
public float m_visible_distance;
public float m_height;
public bool m_reflection;
public bool m_as_actor;
public float m_random_offset_min;
public float m_random_offset_max;
public EffectActorInfo(Dictionary<string, string> createpropdic, int curindx)
{
string nameprefix = "E_" + createpropdic["NamePrefix"];
m_effect_name = nameprefix + "_" + curindx.ToString();
m_resouce_name = createpropdic["ResName"];
if (createpropdic.ContainsKey("可視距離"))
{
if (!float.TryParse(createpropdic["可視距離"], out m_visible_distance))
{
m_visible_distance = 1000;
}
}
else
{
m_visible_distance = 1000;
}
try
{
m_height = float.Parse(createpropdic["Height"]);
}
catch (Exception)
{
m_height = 0;
}
m_reflection = true;
if (createpropdic.ContainsKey("反射中繪制"))
{
bool.TryParse(createpropdic["反射中繪制"], out m_reflection);
}
m_as_actor = false;
if (createpropdic.ContainsKey("受角色光"))
{
bool.TryParse(createpropdic["受角色光"], out m_as_actor);
}
try
{
m_random_offset_min = float.Parse(createpropdic["随機動畫偏移最小值"]);
m_random_offset_max = float.Parse(createpropdic["随機動畫偏移最大值"]);
}
catch (Exception)
{
m_random_offset_min = 0;
m_random_offset_max = 0;
}
}
public EffectActorInfo(string effectname, string resname, float height)
{
m_effect_name = effectname;
m_resouce_name = resname;
m_height = height;
m_visible_distance = 0;
m_reflection = true;
m_as_actor = false;
m_random_offset_min = 0;
m_random_offset_max = 0;
}
public EffectActorInfo(string effectname, string resname, float height, float visible_distance, bool reflection)
{
m_effect_name = effectname;
m_resouce_name = resname;
m_height = height;
m_visible_distance = visible_distance;
m_reflection = reflection;
m_as_actor = false;
m_random_offset_min = 0;
m_random_offset_max = 0;
}
public void toDic(Dictionary<string, string> dic)
{
dic["Name"] = m_effect_name;
dic["ResName"] = m_resouce_name;
dic["Height"] = m_height.ToString();
dic["反射中繪制"] = m_reflection.ToString();
dic["受角色光"] = m_as_actor.ToString();
dic["随機動畫偏移最小值"] = m_random_offset_min.ToString();
dic["随機動畫偏移最大值"] = m_random_offset_max.ToString();
}
public void toDicAll(Dictionary<string, string> dic)
{
dic["Name"] = m_effect_name;
dic["ResName"] = m_resouce_name;
dic["Height"] = m_height.ToString();
dic["可視距離"] = m_visible_distance.ToString();
dic["反射中繪制"] = m_reflection.ToString();
dic["受角色光"] = m_as_actor.ToString();
dic["随機動畫偏移最小值"] = m_random_offset_min.ToString();
dic["随機動畫偏移最大值"] = m_random_offset_max.ToString();
}
// 更新屬性值
public void valueChanged(string key, string value)
{
switch (key)
{
case "Name":
m_effect_name = value;
break;
case "ResName":
m_resouce_name = value;
break;
case "Height":
float.TryParse(value, out m_height);
break;
case "可視距離":
float.TryParse(value, out m_visible_distance);
break;
case "反射中繪制":
bool.TryParse(value, out m_reflection);
break;
case "受角色光":
bool.TryParse(value, out m_as_actor);
break;
case "随機動畫偏移最小值":
float.TryParse(value, out m_random_offset_min);
break;
case "随機動畫偏移最大值":
float.TryParse(value, out m_random_offset_max);
break;
default:
break;
}
}
}
// 特效
public class EffectActor : ResActorBase, IActor
{
public EffectActor(GIIDMng giidmng, Dictionary<string, string> createpropdic, ClientBridge.ClientRenderSys rendersys, int curindex)
: base(giidmng)
{
m_actor_info = new EffectActorInfo(createpropdic, curindex);
m_effect = rendersys.getSpecialEffectMng().loadEffect(m_actor_info.m_resouce_name);
m_effect.play();
}
public EffectActor(GIIDMng giidmng)
: base(giidmng)
{
m_actor_info = new EffectActorInfo();
}
override public void Attach(ClientBridge.SceneBase scene)
{
if (m_effect != null)
{
m_effect.Attach(scene);
}
}
override public void Detach(ClientBridge.SceneBase scene)
{
if (m_effect != null)
{
m_effect.Detach(scene);
}
}
override public void SetLod(ClientBridge.LOD_LEVEL lod)
{
if (m_effect != null)
{
//m_effect.setMaterialLod(lod);
}
}
public override ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_SPE;
}
override public bool hide
{
get { return base.hide; }
set
{
base.hide = value;
//若父層為Hide,則隻改變辨別位,不進行具體操作
if (m_effect != null && !BaseCommand.isActorLayerReadOnly(parentLayer, BaseCommand.ACTORLAYER_ITERATE_MODE.HIDE))
{
m_effect.setVisible(!value);
}
}
}
public override string name
{
get
{
return m_actor_info.m_effect_name;
}
}
public string res
{
get
{
return m_actor_info.m_resouce_name;
}
}
public float visible_distance
{
get
{
return m_actor_info.m_visible_distance;
}
}
public override AxisAlignedBox aabb
{
get { return base.aabb; }
set
{
m_aabb = value;
if (parentLayer != null && this is IActor)
{
parentLayer.OnActorAABBChanged((IActor)this, m_render_aabb);
}
// 更新物品中心
m_center = new Vector3F((m_aabb.Min.X + m_aabb.Max.X) / 2.0f, (m_aabb.Min.Y + m_aabb.Max.Y) / 2.0f, (m_aabb.Min.Z + m_aabb.Max.Z) / 2.0f);
}
}
#region about IDisposable
public void Dispose()
{
//m_effect.release(); // 有問題?
}
#endregion
#region about IActor
public IActor clone(IEditItem edititem)
{
RootEditItem root = (RootEditItem)SceneGraph.getEditItemCommon("RootItem", edititem);
EffectActor actor = null;
return actor;
}
public override IDictionary<string, string> getPropertyList()
{
m_actor_info.toDic(m_property_dic);
return base.getPropertyList();
}
public override void updateLocationAABB()
{
if (m_effect == null)
{
return;
}
List<float> matrix = new List<float>();
for (int i = 0; i < 16; i++)
{
matrix.Add(locationmat[i]);
}
m_effect.setLocationMatrix(matrix);
//m_model.setLocationMatrix(matrix);
// 修改包圍盒
List<float> aabblist = new List<float>();
for (int i = 0; i < 6; i++)
{
aabblist.Add(0);
}
m_effect.getAABB(aabblist);
m_render_aabb = new AxisAlignedBox(new Vector3F(aabblist[0], aabblist[1], aabblist[2]),
new Vector3F(aabblist[3], aabblist[4], aabblist[5]));
Vector3F trans = new Vector3F(locationmat.M14, locationmat.M24, locationmat.M34);
aabb = new AxisAlignedBox(s_min + trans, s_max + trans);
base.updateLocationAABB();
m_pos = new Vector3F(locationmat.M14, locationmat.M24, locationmat.M34);
Vector4F nor = new Vector4F(0, 0, -1, 0);
nor = locationmat * nor;
m_nor = new Vector3F(nor.X, nor.Y, nor.Z);
}
// public override void pushHardwareSelect(ClientBridge.ClientRenderSys rendersys)
// {
//
// }
public override void pushLineHardwareSelect(ClientBridge.ClientRenderSys rendersys)
{
rendersys.pushSelectID((uint)giid.value);
rendersel(0, rendersys);
}
public override void notifyPropertyChange(String key, String value)
{
float min = m_actor_info.m_random_offset_min;
float max = m_actor_info.m_random_offset_max;
bool offsetChanged = false;
base.notifyPropertyChange(key, value);
m_actor_info.valueChanged(key, value);
if (m_effect != null)
{
if (key == "實時陰影")
{
//m_effect.setCastShadow(base.castshadow);
}
else if (key == "反射中繪制")
{
//m_effect.setReflection(m_actor_info.m_reflection);
}
else if (key == "受角色光")
{
//m_effect.asActor(m_actor_info.m_as_actor);
}
else if (key == "随機動畫偏移最小值")
{
if (m_actor_info.m_random_offset_min < 0)
m_actor_info.m_random_offset_min = 0;
if (m_actor_info.m_random_offset_min > m_actor_info.m_random_offset_max)
{
m_actor_info.m_random_offset_max = m_actor_info.m_random_offset_min;
base.notifyPropertyChange("随機動畫偏移最大值", m_actor_info.m_random_offset_max.ToString());
}
offsetChanged = min != m_actor_info.m_random_offset_min;
}
else if (key == "随機動畫偏移最大值")
{
if (m_actor_info.m_random_offset_max < 0)
m_actor_info.m_random_offset_max = 0;
if (m_actor_info.m_random_offset_max < m_actor_info.m_random_offset_min)
{
m_actor_info.m_random_offset_min = m_actor_info.m_random_offset_max;
base.notifyPropertyChange("随機動畫偏移最小值", m_actor_info.m_random_offset_min.ToString());
}
offsetChanged = max != m_actor_info.m_random_offset_max;
}
if (offsetChanged)
setRandomOffsetPlay();
}
}
//設定随機動畫偏移
private void setRandomOffsetPlay()
{
Random ran = new Random(unchecked((int)DateTime.Now.Ticks));
float seed = (float)ran.NextDouble();
float result = (m_actor_info.m_random_offset_max - m_actor_info.m_random_offset_min) * seed + m_actor_info.m_random_offset_min;
m_effect.update(result, false);
}
//通知父層設定了Hide狀态
public override void notifyLayerHide(bool isHide)
{
if (hide)
return;
if (m_effect != null)
m_effect.setVisible(!isHide);
}
//通知父層設定了Freeze狀态
public override void notifyLayerFreeze(bool isFreeze)
{
//base.notifyLayerFreeze(isFreeze);
}
public override string getActorTypestr()
{
return "特效";
}
//public IMemento getMemento(int mode)
//{
// return null;
//}
//public void setMemento(IMemento mem)
//{
//}
public override void update(int t)
{
if (m_effect == null)
{
return;
}
m_effect.update(t);
updateLocationAABB();
}
public override bool serialize(BinaryWriter binWriter)
{
binWriter.Write(m_actor_info.m_effect_name);
binWriter.Write(m_actor_info.m_resouce_name);
binWriter.Write(m_actor_info.m_height);
return base.serialize(binWriter);
}
public override bool serialize(BinaryReader binReader, IEditItem edititem)
{
m_actor_info.m_effect_name = binReader.ReadString();
m_actor_info.m_resouce_name = binReader.ReadString();
m_actor_info.m_height = binReader.ReadSingle();
RootEditItem root = (RootEditItem)(SceneGraph.getEditItemCommon("RootItem", edititem));
m_effect = root.clientRenderSys.getSpecialEffectMng().loadEffect(m_actor_info.m_resouce_name);
m_effect.play();
return base.serialize(binReader, edititem); ;
}
public override void render(int t, ClientBridge.ClientRenderSys rendersys)
{
// 調用自己的繪制函數
if (m_effect == null)
return;
m_effect.render();
}
public void drawRenderLine(int t, ClientBridge.ClientRenderSys rendersys)
{
float[] cy = { 1, 1, 0, 1 };
RenderHelper.RenderConic(0, m_pos, m_nor, 45, 10, cy, rendersys);
}
public void rendersel(int t, ClientBridge.ClientRenderSys rendersys)
{
drawRenderLine(t, rendersys);
}
public override void renderAABB(int t, ClientBridge.ClientRenderSys rendersys, Color color)
{
base.renderAABB(t, rendersys, color);
}
#endregion
public ClientBridge.SpecialEffect m_effect;
EffectActorInfo m_actor_info;
AxisAlignedBox m_render_aabb;
static Vector3F s_min = new Vector3F(-25, -25, -25);
static Vector3F s_max = new Vector3F(25, 25, 25);
Vector3F m_pos = new Vector3F(0, 0, 0);
Vector3F m_nor = new Vector3F(0, 0, -1);
override public string ResName
{
get { return res; }
}
override public object getRes()
{
return m_effect;
}
override public void reload()
{
m_effect.reload();
}
public override void changeRes(ClientBridge.ClientRenderSys rendersys, string new_res)
{
if (m_effect != null)
{
m_effect.changeRes(rendersys, new_res);
m_actor_info.m_resouce_name = new_res;
updateLocationAABB();
}
}
override public void addRef()
{
if (m_effect != null)
{
m_effect.addRef();
}
}
override public int ResRefCount
{
get
{
if (m_effect != null)
{
return m_effect.m_ref_count;
}
else
{
return 0;
}
}
}
}
// 聲音
public class SoundActor : ActorBase, IActor
{
public SoundActor(GIIDMng giidmng)
: base(giidmng)
{
}
public void Dispose()
{
//
}
public override ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_SOUND;
}
#region about IActor
public IActor clone(IEditItem edititem)
{
RootEditItem root = (RootEditItem)SceneGraph.getEditItemCommon("RootItem", edititem);
SoundActor actor = new SoundActor(root.giidmng);
actor.hide = hide;
actor.freeze = freeze;
return actor;
}
new public IMemento getMemento(int mode)
{
return null;
}
new public void setMemento(IMemento mem)
{
}
public override void render(int t, ClientBridge.ClientRenderSys rendersys)
{
// 調用自己的繪制函數
}
#endregion
}
// AI節點
public class AINodeActor : ActorBase, IActor
{
public AINodeActor(GIIDMng giidmng)
: base(giidmng)
{
}
public override ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_AINODE;
}
#region about IDisposable
public void Dispose()
{
//
}
#endregion
#region about IActor
public IActor clone(IEditItem edititem)
{
RootEditItem root = (RootEditItem)SceneGraph.getEditItemCommon("RootItem", edititem);
AINodeActor actor = new AINodeActor(root.giidmng);
actor.hide = hide;
actor.freeze = freeze;
return actor;
}
new public IMemento getMemento(int mode)
{
return null;
}
new public void setMemento(IMemento mem)
{
}
public override void render(int t, ClientBridge.ClientRenderSys rendersys)
{
// 調用自己的繪制函數
}
#endregion
}
public enum LightShape
{
CIRCLE = 0,
RECT = 1
}
// 燈光資訊
public struct LightInfo
{
LightInfo(string type)
{
m_type = type;
m_spe_color = new Color();
m_dif_color = new Color();
m_amb_color = new Color();
}
LightInfo(string type, Color difcolor, Color speccolor, Color ambcolor)
{
m_type = type;
m_dif_color = difcolor;
m_spe_color = speccolor;
m_amb_color = ambcolor;
}
public string m_type;
public Color m_dif_color;
public Color m_spe_color;
public Color m_amb_color;
}
// 區域燈光
public class LightActor : ActorBase, IActor
{
public LightActor(GIIDMng giidmng, LightInfo lightinfo, ClientBridge.ClientRenderSys rendersys)
: base(giidmng)
{
m_light_info = lightinfo;
m_light = rendersys.createLight(lightinfo.m_type);
}
public LightActor(GIIDMng giidmng)
: base(giidmng)
{
m_light_info = new LightInfo();
}
public override ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_LIGHT;
}
public void Dispose()
{
//
}
public IActor clone(IEditItem edititem)
{
RootEditItem root = (RootEditItem)SceneGraph.getEditItemCommon("RootItem", edititem);
LightActor actor = new LightActor(root.giidmng, m_light_info, root.clientRenderSys);
actor.hide = hide;
actor.freeze = freeze;
return actor;
}
new public IMemento getMemento(int mode)
{
return null;
}
new public void setMemento(IMemento mem)
{
}
public override void render(int t, ClientBridge.ClientRenderSys rendersys)
{
// 調用自己的繪制函數
}
override public void Attach(ClientBridge.SceneBase scene)
{
if (m_light != null)
{
//m_light.Attach(scene);
}
}
override public void Detach(ClientBridge.SceneBase scene)
{
if (m_light != null)
{
//m_light.Detach(scene);
}
}
ClientBridge.Light m_light;
LightInfo m_light_info;
}
//操作方式
public enum ActorActionState
{
SELECT,
MOVE,
ROTATE,
DRAG,
RESIZE,
}
// 移動方向
public enum MoveDirection
{
MD_NONE = 0, // 不移動
MD_X = 0x01 << 0, // 沿X軸移動
MD_Y = 0x01 << 1, // 沿Y軸移動
MD_Z = 0x01 << 2, // 沿Z軸移動
MD_XY = MD_X | MD_Y, // 在XY平面移動
MD_XZ = MD_X | MD_Z, // 在XZ平面移動
MD_YZ = MD_Y | MD_Z, // 在YZ平面移動
}
// 旋轉軸
public enum RotateDirection
{
RD_NONE, // 不旋轉
RD_X, // 沿X軸旋轉
RD_Y, // 沿Y軸旋轉
RD_Z // 沿Z軸旋轉
}
// 旋轉方式
public enum RotateMode
{
RM_WHOLE, // 繞同一個軸
RM_SELF, // 繞自身軸
RM_BOTH // fixme:
}
public enum ResizeDirection
{
RD_NONE = 0, // 不移動
RD_X = 0x01 << 0, // 沿X軸移動
RD_Y = 0x01 << 1, // 沿Y軸移動
RD_Z = 0x01 << 2, // 沿Z軸移動
RD_XY = RD_X | RD_Y, // 在XY平面移動
RD_XZ = RD_X | RD_Z, // 在XZ平面移動
RD_YZ = RD_Y | RD_Z,
RD_XYZ = RD_X | RD_Y | RD_Z
}
public class RenderHelper
{
public static float stdDist = 50.0f;
public static float GetFakeLength(Vector3F center, float reallength, float fstdDist, IView view)
{
Vector3F ca_pos = view.getCamera().getCameraPosition();
float dis = ComputeDisBetweenTwoPoint(center, ca_pos);
reallength *= dis / fstdDist;
return reallength;
}
public static void drawCircle(Vector3F center, Vector3F normal, float radius, float[] color, ClientBridge.ClientRenderSys rendersys)
{
normal.Normalize();
// 用360個點的連線模拟圓
int pointcount = 360;
float[] points = new float[pointcount * 3];
//int[] indexs = new int[pointcount*3 + 1];
int[] indexs = new int[pointcount + 1];
for (int t = 0; t < pointcount; t++)
{
float factor = 0;
Vector3F u = new Vector3F();
if (Math.Abs(normal.X) > Math.Abs(normal.Y))
{
factor = 1.0f / (float)Math.Sqrt(normal.X * normal.X + normal.Z * normal.Z);
u.X = -normal.Z * factor;
u.Y = 0;
u.Z = normal.X * factor;
}
else
{
factor = 1.0f / (float)Math.Sqrt(normal.Y * normal.Y + normal.Z * normal.Z);
u.X = 0;
u.Y = normal.Z * factor;
u.Z = -normal.Y * factor;
}
u.Normalize();
Vector3F v = Vector3F.CrossProduct(normal, u);
v.Normalize();
points[t * 3] = (float)(center.X + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.X + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.X);
points[t * 3 + 1] = (float)(center.Y + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Y + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Y);
points[t * 3 + 2] = (float)(center.Z + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Z + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Z);
indexs[t] = t;
}
indexs[pointcount] = 0;
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs, color, true);
}
public static void drawRotateCircles(Vector3F center, IView view, float[] circlexy, float[] circleyz, float[] circlexz, bool hardsel)
{
drawRotateCircles(center, view, circlexy, circleyz, circlexz, hardsel, Matrix3F.Identity);
}
public static void drawRotateCircles(Vector3F center, IView view, float[] circlexy, float[] circleyz, float[] circlexz, bool hardsel, Matrix3F rotmat)
{
drawRotateCircles(center, view, 10.0f, circlexy, circleyz, circlexz, hardsel, rotmat);
}
public static void DrawMoustSelectRect(int x1, int y1, int x2, int y2, IView view)
{
Vector3F p1 = view.getCamera().GetScreenXYZ(x1, y1, view.getRenderSys());
Vector3F p2 = view.getCamera().GetScreenXYZ(x2, y2, view.getRenderSys());
Vector3F p3 = view.getCamera().GetScreenXYZ(x1, y2, view.getRenderSys());
Vector3F p4 = view.getCamera().GetScreenXYZ(x2, y1, view.getRenderSys());
Vector3F p_p1 = new Vector3F(p1.X - view.getCamera().position.x, p1.Y - view.getCamera().position.y, p1.Z - view.getCamera().position.z);
Vector3F p_p2 = new Vector3F(p2.X - view.getCamera().position.x, p2.Y - view.getCamera().position.y, p2.Z - view.getCamera().position.z);
Vector3F p_p3 = new Vector3F(p3.X - view.getCamera().position.x, p3.Y - view.getCamera().position.y, p3.Z - view.getCamera().position.z);
Vector3F p_p4 = new Vector3F(p4.X - view.getCamera().position.x, p4.Y - view.getCamera().position.y, p4.Z - view.getCamera().position.z);
float e = 0.01f;
float[] color = { 1, 1, 1, 1 };
p_p1.Normalize();
p_p2.Normalize();
p_p3.Normalize();
p_p4.Normalize();
p1 += p_p1 * e;
p2 += p_p2 * e;
p3 += p_p3 * e;
p4 += p_p4 * e;
float[] points = { p1.X, p1.Y, p1.Z, p3.X, p3.Y, p3.Z, p2.X, p2.Y, p2.Z, p4.X, p4.Y, p4.Z, };
view.getRenderSys().drawMouseSelectRect(points, color);
}
public static void drawRotateCircles(Vector3F center, IView view, float coord_length, float[] circlexy, float[] circleyz, float[] circlexz, bool hardsel, Matrix3F rotmat)
{
ClientBridge.ClientRenderSys rendersys = view.getRenderSys();
float length = coord_length;
length = GetFakeLength(center, length, stdDist, view);
Vector3F coord_x = Matrix3F.Transform(rotmat, new Vector3F(1, 0, 0));
Vector3F coord_y = Matrix3F.Transform(rotmat, new Vector3F(0, 1, 0));
Vector3F coord_z = Matrix3F.Transform(rotmat, new Vector3F(0, 0, 1));
if (hardsel)
{
rendersys.pushSelectID(0);
}
drawCircle(center, coord_x, length, circleyz, rendersys); // 繪制垂直于x軸的圓
if (hardsel)
{
rendersys.pushSelectID(1);
}
drawCircle(center, coord_y, length, circlexz, rendersys); // 繪制垂直于y軸的圓
if (hardsel)
{
rendersys.pushSelectID(2);
}
drawCircle(center, coord_z, length, circlexy, rendersys); // 繪制垂直于z軸的圓
coord_x = length * coord_x + center;
coord_y = length * coord_y + center;
coord_z = length * coord_z + center;
float[] points = { center.X, center.Y, center.Z, // 0 o
coord_x.X, coord_x.Y, coord_x.Z, // 1 x
coord_y.X, coord_y.Y, coord_y.Z, // 2 y
coord_z.X, coord_z.Y, coord_z.Z, // 3 z
};
int[] indexsx = { 0, 1 };
int[] indexsy = { 0, 2 };
int[] indexsz = { 0, 3 };
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexsx, circleyz, true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexsy, circlexz, true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexsz, circlexy, true);
}
public static void renderCoordinate(Vector3F center, IView view, float[] colorx, float[] colory, float[] colorz, float[] colorxy, float[] coloryz, float[] colorxz, bool hardsel)
{
renderCoordinate(center, view, colorx, colory, colorz, colorxy, coloryz, colorxz, hardsel, Matrix3F.Identity);
}
public static void renderCoordinate(Vector3F center, IView view, float[] colorx, float[] colory, float[] colorz, float[] colorxy, float[] coloryz, float[] colorxz, bool hardsel, Matrix3F rotmat)
{
renderCoordinate(center, view, 10.0f, colorx, colory, colorz, colorxy, coloryz, colorxz, hardsel, rotmat);
}
public static void renderCoordinate(Vector3F center, IView view, float coord_length, float[] colorx, float[] colory, float[] colorz, float[] colorxy, float[] coloryz, float[] colorxz, bool hardsel, Matrix3F rotmat)
{
ClientBridge.ClientRenderSys rendersys = view.getRenderSys();
float length = coord_length;
length = GetFakeLength(center, length, stdDist, view);
float length1 = length / 2.0f;
Vector3F coord_x = center + Matrix3F.Transform(rotmat, new Vector3F(length, 0, 0));
Vector3F coord_y = center + Matrix3F.Transform(rotmat, new Vector3F(0, length, 0));
Vector3F coord_z = center + Matrix3F.Transform(rotmat, new Vector3F(0, 0, length));
Vector3F coord_xh = center + Matrix3F.Transform(rotmat, new Vector3F(length1, 0, 0));
Vector3F coord_yh = center + Matrix3F.Transform(rotmat, new Vector3F(0, length1, 0));
Vector3F coord_zh = center + Matrix3F.Transform(rotmat, new Vector3F(0, 0, length1));
Vector3F coord_xy = center + Matrix3F.Transform(rotmat, new Vector3F(length1, length1, 0));
Vector3F coord_xz = center + Matrix3F.Transform(rotmat, new Vector3F(length1, 0, length1));
Vector3F coord_yz = center + Matrix3F.Transform(rotmat, new Vector3F(0, length1, length1));
float[] points = { center.X , center.Y , center.Z , // 0 o
coord_x.X , coord_x.Y , coord_x.Z , // 1 x
coord_y.X , coord_y.Y , coord_y.Z , // 2 y
coord_z.X , coord_z.Y , coord_z.Z , // 3 z
coord_xh.X, coord_xh.Y, coord_xh.Z, // 4 x_h
coord_yh.X, coord_yh.Y, coord_yh.Z, // 5 y_h
coord_zh.X, coord_zh.Y, coord_zh.Z, // 6 z_h
coord_xy.X, coord_xy.Y, coord_xy.Z, // 7 x_y
coord_xz.X, coord_xz.Y, coord_xz.Z, // 8 x_z
coord_yz.X, coord_yz.Y, coord_yz.Z // 9 y_z
};
int[] indexs_x = { 0, 1 }; // x軸索引
int[] indexs_y = { 0, 2 }; // y軸索引
int[] indexs_z = { 0, 3 }; // z軸索引
int[] indexs_xy = { 4, 7, 5 }; // xy夾角索引
int[] indexs_xz = { 4, 8, 6 }; // xz夾角索引
int[] indexs_yz = { 5, 9, 6 }; // yz夾角索引
if (hardsel)
{
rendersys.pushSelectID(0);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_x, colorx, true);
if (hardsel)
{
rendersys.pushSelectID(1);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_y, colory, true);
if (hardsel)
{
rendersys.pushSelectID(2);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_z, colorz, true);
if (hardsel)
{
rendersys.pushSelectID(3);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_xy, colorxy, true);
if (hardsel)
{
rendersys.pushSelectID(4);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_xz, colorxz, true);
if (hardsel)
{
rendersys.pushSelectID(5);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_yz, coloryz, true);
if (hardsel)
{
rendersys.pushSelectID(0);
}
RenderPyramid(coord_x, coord_x - center, length / 3, colorx, rendersys);
if (hardsel)
{
rendersys.pushSelectID(1);
}
RenderPyramid(coord_y, coord_y - center, length / 3, colory, rendersys);
if (hardsel)
{
rendersys.pushSelectID(2);
}
RenderPyramid(coord_z, coord_z - center, length / 3, colorz, rendersys);
}
public static void renderResizeCoordinate(ResizeDirection rd, Vector3F center, IView view, float[] colorx, float[] colory, float[] colorz, float[] colorxy, float[] coloryz, float[] colorxz, float[] colorxyz, bool hardsel)
{
renderResizeCoordinate(rd, center, 10.0f, view, colorx, colory, colorz, colorxy, coloryz, colorxz, colorxyz, hardsel);
}
public static void renderResizeCoordinate(ResizeDirection rd, Vector3F center, float coord_length, IView view, float[] colorx, float[] colory, float[] colorz, float[] colorxy, float[] coloryz, float[] colorxz, float[] colorxyz, bool hardsel)
{
ClientBridge.ClientRenderSys rendersys = view.getRenderSys();
float length = coord_length;
length = GetFakeLength(center, length, stdDist, view);
Vector3F coordx = center + new Vector3F(length, 0, 0);
Vector3F coordy = center + new Vector3F(0, length, 0);
Vector3F coordz = center + new Vector3F(0, 0, length);
float length1 = length * 2 / 3;
float length2 = length / 2;
float[] points = { center.X, center.Y, center.Z, // 0 o
center.X + length, center.Y, center.Z, // 1 x
center.X, center.Y + length, center.Z, // 2 y
center.X, center.Y,center.Z + length, // 3 z
center.X + length1, center.Y, center.Z, // 4 x_h
center.X, center.Y + length1, center.Z, // 5 y_h
center.X, center.Y, center.Z + length1, // 6 z_h
center.X + length2, center.Y, center.Z, //7
center.X, center.Y + length2, center.Z, //8
center.X, center.Y, center.Z + length2, //9
};
int[] indexs_x = { 0, 1 }; // x軸索引
int[] indexs_y = { 0, 2 }; // y軸索引
int[] indexs_z = { 0, 3 }; // z軸索引
int[] indexs_xyl = { 4, 5, 7, 8 };
int[] indexs_xzl = { 4, 6, 7, 9 };
int[] indexs_yzl = { 5, 6, 8, 9 };
int[] indexs_xz = { 4, 6, 7, 7, 6, 9 }; // xy夾角索引
int[] indexs_xy = { 4, 7, 5, 7, 8, 5 }; // xz夾角索引
int[] indexs_yz = { 9, 6, 8, 8, 6, 5 }; // yz夾角索引
int[] indexs_xyz = { 7, 9, 8 };
if (hardsel)
{
rendersys.pushSelectID(0);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_x, colorx, true);
if (hardsel)
{
rendersys.pushSelectID(1);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_y, colory, true);
if (hardsel)
{
rendersys.pushSelectID(2);
}
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs_z, colorz, true);
if (hardsel)
{
rendersys.pushSelectID(3);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs_xy, colorxy, true);
}
else
{
if (rd == ResizeDirection.RD_XY)
{
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs_xy, colorxy, true);
}
else
{
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexs_xyl, colorxy, true);
}
}
if (hardsel)
{
rendersys.pushSelectID(4);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs_xz, colorxz, true);
}
else
{
if (rd == ResizeDirection.RD_XZ)
{
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs_xz, colorxz, true);
}
else
{
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexs_xzl, colorxz, true);
}
}
if (hardsel)
{
rendersys.pushSelectID(5);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs_yz, coloryz, true);
}
else
{
if (rd == ResizeDirection.RD_YZ)
{
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs_yz, coloryz, true);
}
else
{
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexs_yzl, coloryz, true);
}
}
if (hardsel)
{
rendersys.pushSelectID(6);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs_xyz, colorxyz, true);
}
else
{
if (rd == ResizeDirection.RD_XYZ)
{
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs_xyz, colorxyz, true);
}
}
RenderPyramid(coordx, coordx - center, length / 3, colorx, rendersys);
RenderPyramid(coordy, coordy - center, length / 3, colory, rendersys);
RenderPyramid(coordz, coordz - center, length / 3, colorz, rendersys);
}
public static MoveDirection SelectMoveLines(Vector3F center, System.Drawing.Point point, IView view)
{
return SelectMoveLines(center, point, view, Matrix3F.Identity);
}
public static MoveDirection SelectMoveLines(Vector3F center, System.Drawing.Point point, IView view, Matrix3F rotmat)
{
return SelectMoveLines(center, point, view, 10.0f, rotmat);
}
public static MoveDirection SelectMoveLines(Vector3F center, System.Drawing.Point point, IView view, float length, Matrix3F rotmat)
{
view.setCamera();
view.getRenderSys().beginHardwareSelect(new int[] { point.X - Tool.SelLine_EdgeWidth, point.Y - Tool.SelLine_EdgeWidth, 2 * Tool.SelLine_EdgeWidth, 2 * Tool.SelLine_EdgeWidth }, true);
renderCoordinate(center, view, length, Tool.Red, Tool.Green, Tool.Blue, Tool.White, Tool.White, Tool.White, true, rotmat);
uint[] res = view.getRenderSys().endHardwareSelect();
if (res != null && res.GetLength(0) > 0)
{
switch (res[0])
{
case 0:
return MoveDirection.MD_X;
case 1:
return MoveDirection.MD_Y;
case 2:
return MoveDirection.MD_Z;
case 3:
return MoveDirection.MD_XY;
case 4:
return MoveDirection.MD_XZ;
case 5:
return MoveDirection.MD_YZ;
default:
return MoveDirection.MD_NONE;
}
}
else
{
return MoveDirection.MD_NONE;
}
}
public static RotateDirection SelectRotateCircles(Vector3F center, System.Drawing.Point point, IView view)
{
return SelectRotateCircles(center, point, view, Matrix3F.Identity);
}
public static RotateDirection SelectRotateCircles(Vector3F center, System.Drawing.Point point, IView view, Matrix3F rotmat)
{
return SelectRotateCircles(center, point, 10.0f, view, rotmat);
}
public static RotateDirection SelectRotateCircles(Vector3F center, System.Drawing.Point point, float length, IView view, Matrix3F rotmat)
{
view.setCamera();
view.getRenderSys().beginHardwareSelect(new int[] { point.X - Tool.SelLine_EdgeWidth, point.Y - Tool.SelLine_EdgeWidth, 2 * Tool.SelLine_EdgeWidth, 2 * Tool.SelLine_EdgeWidth }, true);
drawRotateCircles(center, view, length, Tool.Red, Tool.Green, Tool.Blue, true, rotmat);
uint[] res = view.getRenderSys().endHardwareSelect();
if (res != null && res.GetLength(0) > 0)
{
switch (res[0])
{
case 0:
return RotateDirection.RD_X;
case 1:
return RotateDirection.RD_Y;
case 2:
return RotateDirection.RD_Z;
default:
return RotateDirection.RD_NONE;
}
}
else
{
return RotateDirection.RD_NONE;
}
}
public static ResizeDirection SelectResizeDirection(Vector3F center, System.Drawing.Point point, IView view)
{
return SelectResizeDirection(center, point, 10.0f, view);
}
public static ResizeDirection SelectResizeDirection(Vector3F center, System.Drawing.Point point, float length, IView view)
{
view.setCamera();
view.getRenderSys().beginHardwareSelect(new int[] { point.X - Tool.SelLine_EdgeWidth, point.Y - Tool.SelLine_EdgeWidth, 2 * Tool.SelLine_EdgeWidth, 2 * Tool.SelLine_EdgeWidth }, true);
renderResizeCoordinate(ResizeDirection.RD_NONE, center, length, view, Tool.Red, Tool.Green, Tool.Blue, Tool.White, Tool.White, Tool.White, Tool.White, true);
uint[] res = view.getRenderSys().endHardwareSelect();
if (res != null && res.GetLength(0) > 0)
{
switch (res[0])
{
case 0:
return ResizeDirection.RD_X;
case 1:
return ResizeDirection.RD_Y;
case 2:
return ResizeDirection.RD_Z;
case 3:
return ResizeDirection.RD_XY;
case 4:
return ResizeDirection.RD_XZ;
case 5:
return ResizeDirection.RD_YZ;
case 6:
return ResizeDirection.RD_XYZ;
default:
return ResizeDirection.RD_NONE;
}
}
else
{
return ResizeDirection.RD_NONE;
}
}
//兩個點相減求向量 并歸一化
public static Vector3F ComputeVectorAndNormalize(Vector3F start, Vector3F end)
{
Vector3F res = Vector3F.Subtract(end, start);
float length = (float)Math.Sqrt(res.X * res.X + res.Y * res.Y + res.Z * res.Z);
res.X /= length;
res.Y /= length;
res.Z /= length;
return res;
}
//求兩個點之間的距離
public static float ComputeDisBetweenTwoPoint(Vector3F start, Vector3F end)
{
Vector3F res = Vector3F.Subtract(end, start);
return (float)Math.Sqrt(res.X * res.X + res.Y * res.Y + res.Z * res.Z);
}
//給定球心和半徑,求頂點
private static void ComputePointVertex(Vector3F center, float radius, float[] points)
{
float da = (float)Math.PI / 5;
float cos_da = (float)Math.Cos(da);
float sin_da = (float)Math.Sin(da);
float dx1 = radius * (float)Math.Sin(Math.PI / 3);
float dy1 = 0;
float dx2 = radius;
float dy2 = 0;
float z1 = center.Z + radius / 2;
float z2 = center.Z - radius / 2;
points[0] = center.X;
points[1] = center.Y;
points[2] = center.Z + radius;
points[93] = center.X;
points[94] = center.Y;
points[95] = center.Z - radius;
for (int i = 0; i < 10; ++i)
{
int index = 3 * i;
// 點
points[index + 3] = dx1 * cos_da - dy1 * sin_da;
points[index + 4] = dx1 * sin_da + dy1 * cos_da;
dx1 = points[index + 3];
dy1 = points[index + 4];
points[index + 3] += center.X;
points[index + 4] += center.Y;
points[index + 5] = z1;
points[index + 33] = dx2 * cos_da - dy2 * sin_da;
points[index + 34] = dx2 * sin_da + dy2 * cos_da;
dx2 = points[index + 33];
dy2 = points[index + 34];
points[index + 33] += center.X;
points[index + 34] += center.Y;
points[index + 35] = center.Z;
points[index + 63] = points[index + 3];
points[index + 64] = points[index + 4];
points[index + 65] = z2;
}
}
public static void RenderMoveCoordinate(MoveDirection md, Vector3F center, IView view)
{
RenderMoveCoordinate(md, center, view, Matrix3F.Identity);
}
public static void RenderMoveCoordinate(MoveDirection md, Vector3F center, IView view, Matrix3F rotmat)
{
RenderMoveCoordinate(md, center, view, 10.0f, rotmat);
}
public static void RenderMoveCoordinate(MoveDirection md, Vector3F center, IView view, float length, Matrix3F rotmat)
{
switch (md)
{
case MoveDirection.MD_X:
RenderHelper.renderCoordinate(center, view, length, Tool.Yellow, Tool.Green, Tool.Blue, Tool.White, Tool.White, Tool.White, false, rotmat);
break;
case MoveDirection.MD_Y:
RenderHelper.renderCoordinate(center, view, length, Tool.Red, Tool.Yellow, Tool.Blue, Tool.White, Tool.White, Tool.White, false, rotmat);
break;
case MoveDirection.MD_Z:
RenderHelper.renderCoordinate(center, view, length, Tool.Red, Tool.Green, Tool.Yellow, Tool.White, Tool.White, Tool.White, false, rotmat);
break;
case MoveDirection.MD_XY:
RenderHelper.renderCoordinate(center, view, length, Tool.Red, Tool.Green, Tool.Blue, Tool.Yellow, Tool.White, Tool.White, false, rotmat);
break;
case MoveDirection.MD_XZ:
RenderHelper.renderCoordinate(center, view, length, Tool.Red, Tool.Green, Tool.Blue, Tool.White, Tool.White, Tool.Yellow, false, rotmat);
break;
case MoveDirection.MD_YZ:
RenderHelper.renderCoordinate(center, view, length, Tool.Red, Tool.Green, Tool.Blue, Tool.White, Tool.Yellow, Tool.White, false, rotmat);
break;
case MoveDirection.MD_NONE:
RenderHelper.renderCoordinate(center, view, length, Tool.Red, Tool.Green, Tool.Blue, Tool.White, Tool.White, Tool.White, false, rotmat);
break;
default:
break;
}
}
public static void RenderRotateCircles(RotateDirection rd, Vector3F center, IView view)
{
RenderRotateCircles(rd, center, view, Matrix3F.Identity);
}
public static void RenderRotateCircles(RotateDirection rd, Vector3F center, IView view, Matrix3F rotmat)
{
RenderRotateCircles(rd, 10.0f, center, view, rotmat);
}
public static void RenderRotateCircles(RotateDirection rd, float length, Vector3F center, IView view, Matrix3F rotmat)
{
switch (rd)
{
case RotateDirection.RD_X:
RenderHelper.drawRotateCircles(center, view, length, Tool.Blue, Tool.Yellow, Tool.Green, false, rotmat);
break;
case RotateDirection.RD_Y:
RenderHelper.drawRotateCircles(center, view, length, Tool.Blue, Tool.Red, Tool.Yellow, false, rotmat);
break;
case RotateDirection.RD_Z:
RenderHelper.drawRotateCircles(center, view, length, Tool.Yellow, Tool.Red, Tool.Green, false, rotmat);
break;
case RotateDirection.RD_NONE:
RenderHelper.drawRotateCircles(center, view, length, Tool.Blue, Tool.Red, Tool.Green, false, rotmat);
break;
default:
RenderHelper.drawRotateCircles(center, view, length, Tool.Blue, Tool.Red, Tool.Green, false, rotmat);
break;
}
}
public static void RenderResizeCoordinate(ResizeDirection rd, Vector3F center, IView view)
{
RenderResizeCoordinate(rd, center, 10.0f, view);
}
public static void RenderResizeCoordinate(ResizeDirection rd, Vector3F center, float length, IView view)
{
switch (rd)
{
case ResizeDirection.RD_X:
RenderHelper.renderResizeCoordinate(rd, center, length, view, Tool.Yellow, Tool.Green, Tool.Blue, Tool.Yellow, Tool.Yellow, Tool.Yellow, Tool.Yellow, false);
break;
case ResizeDirection.RD_Y:
RenderHelper.renderResizeCoordinate(rd, center, length, view, Tool.Red, Tool.Yellow, Tool.Blue, Tool.Yellow, Tool.Yellow, Tool.Yellow, Tool.Yellow, false);
break;
case ResizeDirection.RD_Z:
RenderHelper.renderResizeCoordinate(rd, center, length, view, Tool.Red, Tool.Green, Tool.Yellow, Tool.Yellow, Tool.Yellow, Tool.Yellow, Tool.Yellow, false);
break;
case ResizeDirection.RD_XY:
RenderHelper.renderResizeCoordinate(rd, center, length, view, Tool.Red, Tool.Green, Tool.Blue, Tool.Purple, Tool.Yellow, Tool.Yellow, Tool.Yellow, false);
break;
case ResizeDirection.RD_XZ:
RenderHelper.renderResizeCoordinate(rd, center, length, view, Tool.Red, Tool.Green, Tool.Blue, Tool.Yellow, Tool.Yellow, Tool.Purple, Tool.Yellow, false);
break;
case ResizeDirection.RD_YZ:
RenderHelper.renderResizeCoordinate(rd, center, length, view, Tool.Red, Tool.Green, Tool.Blue, Tool.Yellow, Tool.Purple, Tool.Yellow, Tool.Yellow, false);
break;
case ResizeDirection.RD_XYZ:
RenderHelper.renderResizeCoordinate(rd, center, length, view, Tool.Red, Tool.Green, Tool.Blue, Tool.Yellow, Tool.Yellow, Tool.Yellow, Tool.Purple, false);
break;
case ResizeDirection.RD_NONE:
RenderHelper.renderResizeCoordinate(rd, center, length, view, Tool.Red, Tool.Green, Tool.Blue, Tool.Yellow, Tool.Yellow, Tool.Yellow, Tool.Yellow, false);
break;
default:
break;
}
}
public static void Draw2DViewRect(int x1, int y1, int x2, int y2, IView view)
{
Vector3F p1 = view.getCamera().GetScreenXYZ(x1, y1, view.getRenderSys());
Vector3F p2 = view.getCamera().GetScreenXYZ(x2, y2, view.getRenderSys());
Vector3F p3 = view.getCamera().GetScreenXYZ(x1, y2, view.getRenderSys());
Vector3F p4 = view.getCamera().GetScreenXYZ(x2, y1, view.getRenderSys());
Vector3F p_p1 = new Vector3F(p1.X - view.getCamera().position.x, p1.Y - view.getCamera().position.y, p1.Z - view.getCamera().position.z);
Vector3F p_p2 = new Vector3F(p2.X - view.getCamera().position.x, p2.Y - view.getCamera().position.y, p2.Z - view.getCamera().position.z);
Vector3F p_p3 = new Vector3F(p3.X - view.getCamera().position.x, p3.Y - view.getCamera().position.y, p3.Z - view.getCamera().position.z);
Vector3F p_p4 = new Vector3F(p4.X - view.getCamera().position.x, p4.Y - view.getCamera().position.y, p4.Z - view.getCamera().position.z);
float e = 0.01f;
float[] color = { 1, 1, 1, 1 };
p_p1.Normalize();
p_p2.Normalize();
p_p3.Normalize();
p_p4.Normalize();
p1 += p_p1 * e;
p2 += p_p2 * e;
p3 += p_p3 * e;
p4 += p_p4 * e;
view.getRenderSys().drawLine(p1.X, p1.Y, p1.Z, p3.X, p3.Y, p3.Z, color);
view.getRenderSys().drawLine(p1.X, p1.Y, p1.Z, p4.X, p4.Y, p4.Z, color);
view.getRenderSys().drawLine(p2.X, p2.Y, p2.Z, p3.X, p3.Y, p3.Z, color);
view.getRenderSys().drawLine(p2.X, p2.Y, p2.Z, p4.X, p4.Y, p4.Z, color);
}
public static void DrawDirectionArrow(Vector3F start, Matrix4F locationmat, IView view)
{
Vector3F dir = new Vector3F(0, -1, 0);
Matrix4F tmp = TransformationF.Translation(dir);
Matrix4F res = locationmat * tmp;
Vector3F end = new Vector3F(res.M14, res.M24, res.M34);
dir = new Vector3F(locationmat.M14, locationmat.M24, locationmat.M34);
DrawDirectionArrow(start, end - dir, view);
}
public static void DrawDirectionArrow(Vector3F start, Vector3F dir, IView view)
{
float length1 = 6;
float length2 = 1;
length1 = RenderHelper.GetFakeLength(start, length1, RenderHelper.stdDist, view);
Vector3F end = RenderHelper.GetPointDisNToPoint(start, dir, length1);
RenderHelper.DrawLinkLine(start, end, Tool.Yellow, view.getRenderSys());
length2 = RenderHelper.GetFakeLength(end, length2, RenderHelper.stdDist, view);
RenderHelper.RenderConic((int)LightShape.CIRCLE, end, -dir, 45, length2, Tool.Yellow, view.getRenderSys());
}
//畫一個球體
public static void DrawPoint(Vector3F center, float radius, float[] color, IView view)
{
ClientBridge.ClientRenderSys crs = view.getRenderSys();
float[] points = new float[96]; // 32個點
int[] indexs = new int[180]; // 60個三角形
radius = GetFakeLength(center, radius, stdDist, view);
ComputePointVertex(center, radius, points);
for (int i = 0; i < 10; ++i)
{
int index = 3 * i;
// 三角形索引
indexs[index] = 0;
indexs[index + 1] = (i + 1) % 10 + 1;
indexs[index + 2] = i + 1;
indexs[index + 30] = indexs[index + 2];
indexs[index + 31] = indexs[index + 1];
indexs[index + 32] = indexs[index + 31] + 10;
indexs[index + 60] = indexs[index + 30];
indexs[index + 61] = indexs[index + 32];
indexs[index + 62] = indexs[index + 30] + 10;
indexs[index + 90] = indexs[index + 62];
indexs[index + 91] = indexs[index + 61];
indexs[index + 92] = indexs[index + 91] + 10;
indexs[index + 120] = indexs[index + 90];
indexs[index + 121] = indexs[index + 92];
indexs[index + 122] = indexs[index + 90] + 10;
indexs[index + 150] = indexs[index + 122];
indexs[index + 151] = indexs[index + 121];
indexs[index + 152] = 31;
}
crs.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs, color, false);
}
//畫一個球的網格
public static void DrawPointGrid(Vector3F center, float radius, float[] color, ClientBridge.ClientRenderSys crs)
{
float[] points = new float[96]; // 32個點
int[] indexs = new int[180]; // 90條邊
ComputePointVertex(center, radius, points);
for (int i = 0; i < 10; i++)
{
int index = 2 * i;
indexs[index] = 0;
indexs[index + 1] = i + 1;
}
for (int i = 0; i < 10; i++)
{
int index = 2 * i;
indexs[index + 20] = indexs[index + 1];
indexs[index + 21] = indexs[index + 3 > 19 ? 1 : index + 3];
indexs[index + 80] = indexs[index + 20] + 10;
indexs[index + 81] = indexs[index + 21] + 10;
indexs[index + 40] = indexs[index + 20];
indexs[index + 41] = indexs[index + 80];
indexs[index + 60] = indexs[index + 20];
indexs[index + 61] = indexs[index + 81 > 99 ? index + 80 : index + 81];
indexs[index + 140] = indexs[index + 80] + 10;
indexs[index + 141] = indexs[index + 81] + 10;
indexs[index + 100] = indexs[index + 80];
indexs[index + 101] = indexs[index + 140];
indexs[index + 120] = indexs[index + 80];
indexs[index + 121] = indexs[index + 141 > 159 ? index + 140 : index + 141];
indexs[index + 160] = indexs[index + 140];
indexs[index + 161] = 31;
}
crs.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexs, color, false);
}
//畫非點光源的起點和終點之間的連接配接線
public static void DrawLinkLine(Vector3F start, Vector3F end, float[] color, ClientBridge.ClientRenderSys crs)
{
float[] points = {start.X, start.Y, start.Z,
end.X, end.Y, end.Z};
crs.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, new int[] { 0, 1 }, color, false);
}
public static Vector3F GetPointDisNToPoint(Vector3F start, Vector3F dir, float dis)
{
float x = 0, y = 0, z = 0;
int index = 0;
float m = 0, n = 0;
float tmp = 0;
if (dis == 0)
{
return new Vector3F(start);
}
else if (dis < 0)
{
dis = -dis;
dir = Vector3F.Negate(dir);
}
if (dir.Z != 0)
{
m = dir.Z;
n = start.Z;
index = 1;
}
else if (dir.X != 0)
{
m = dir.X;
n = start.X;
index = 2;
}
else if (dir.Y != 0)
{
m = dir.Y;
n = start.Y;
index = 3;
}
else
{
return new Vector3F();
}
tmp = dis * dis * m * m;
tmp /= (dir.X * dir.X + dir.Y * dir.Y + dir.Z * dir.Z);
tmp = (float)Math.Sqrt(tmp);
if (tmp * m < 0)
{
tmp = -tmp;
}
tmp += n;
if (index == 1)
{
z = tmp;
if (dir.X != 0)
{
x = dir.X * (z - start.Z) / dir.Z + start.X;
}
else
{
x = start.X;
}
if (dir.Y != 0)
{
y = dir.Y * (z - start.Z) / dir.Z + start.Y;
}
else
{
y = start.Y;
}
}
if (index == 2)
{
x = tmp;
if (dir.Y != 0)
{
y = dir.Y * (x - start.X) / dir.X + start.Y;
}
else
{
y = start.Y;
}
if (dir.Z != 0)
{
z = dir.Z * (x - start.X) / dir.X + start.Z;
}
else
{
z = start.Z;
}
}
if (index == 3)
{
y = tmp;
if (dir.X != 0)
{
x = dir.X * (y - start.Y) / dir.Y + start.X;
}
else
{
x = start.X;
}
if (dir.Z != 0)
{
z = dir.Z * (y - start.Y) / dir.Y + start.Z;
}
else
{
z = start.Z;
}
}
return new Vector3F(x, y, z);
}
//求線段上距起點一定距離的點
public static Vector3F GetPointDisNToPointOnLine(Vector3F start, Vector3F end, float dis)
{
Vector3F direct = Vector3F.Subtract(start, end);
return GetPointDisNToPoint(start, direct, dis);
}
public static void RenderCube(Vector3F center, Vector3F normal, float radis, float length, float[] color, ClientBridge.ClientRenderSys rendersys)
{
RenderCube(center, normal, radis, length, color, rendersys, false);
}
public static void RenderCube(Vector3F center, Vector3F normal, float radis, float length, float[] color, ClientBridge.ClientRenderSys rendersys, bool hardsel)
{
RenderCube(center, normal, radis, length, color, rendersys, hardsel, false);
}
public static void RenderCube(Vector3F center, Vector3F normal, float radis, float length, float[] color, ClientBridge.ClientRenderSys rendersys, bool hardsel, bool hidesee)
{
float[] points = new float[24];
float radius = radis * ((float)Math.Sqrt(2));
Vector3F center2 = GetPointDisNToPoint(center, normal, length);
if (normal.GetLength() != 0)
{
normal.Normalize();
}
for (int t = 0; t < 4; t++)
{
float factor = 0;
Vector3F u = new Vector3F();
if (Math.Abs(normal.X) > Math.Abs(normal.Y))
{
factor = 1.0f / (float)Math.Sqrt(normal.X * normal.X + normal.Z * normal.Z);
u.X = -normal.Z * factor;
u.Y = 0;
u.Z = normal.X * factor;
}
else
{
factor = 1.0f / (float)Math.Sqrt(normal.Y * normal.Y + normal.Z * normal.Z);
u.X = 0;
u.Y = normal.Z * factor;
u.Z = -normal.Y * factor;
}
u.Normalize();
Vector3F v = Vector3F.CrossProduct(normal, u);
v.Normalize();
points[t * 3] = (float)(center.X + (radius * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.X + (radius * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.X);
points[t * 3 + 1] = (float)(center.Y + (radius * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.Y + (radius * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.Y);
points[t * 3 + 2] = (float)(center.Z + (radius * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.Z + (radius * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.Z);
points[12 + t * 3] = (float)(center2.X + (radius * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.X + (radius * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.X);
points[12 + t * 3 + 1] = (float)(center2.Y + (radius * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.Y + (radius * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.Y);
points[12 + t * 3 + 2] = (float)(center2.Z + (radius * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.Z + (radius * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.Z);
}
if (hardsel)
{
int[] indexs = new int[36] { 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 0, 1, 5, 0, 5, 4, 1, 2, 6, 1, 6, 5, 2, 3, 7, 2, 7, 6, 3, 0, 4, 3, 4, 7 };
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs, color, hidesee);
}
else
{
int[] indexs = new int[24] { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexs, color, hidesee);
}
}
public static void RenderCloumn(Vector3F center, Vector3F normal, float radius, float length, float[] color, ClientBridge.ClientRenderSys rendersys)
{
normal.Normalize();
Vector3F center2 = GetPointDisNToPoint(center, normal, length);
int pointcount = 360;
float[] points1 = new float[pointcount * 3];
int[] indexs1 = new int[pointcount + 1];
float[] points2 = new float[pointcount * 3];
int[] indexs2 = new int[pointcount + 1];
float[] points3 = new float[24];
int i = 0;
for (int t = 0; t < pointcount; t++)
{
float factor = 0;
Vector3F u = new Vector3F();
if (Math.Abs(normal.X) > Math.Abs(normal.Y))
{
factor = 1.0f / (float)Math.Sqrt(normal.X * normal.X + normal.Z * normal.Z);
u.X = -normal.Z * factor;
u.Y = 0;
u.Z = normal.X * factor;
}
else
{
factor = 1.0f / (float)Math.Sqrt(normal.Y * normal.Y + normal.Z * normal.Z);
u.X = 0;
u.Y = normal.Z * factor;
u.Z = -normal.Y * factor;
}
u.Normalize();
Vector3F v = Vector3F.CrossProduct(normal, u);
v.Normalize();
points1[t * 3] = (float)(center.X + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.X + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.X);
points1[t * 3 + 1] = (float)(center.Y + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Y + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Y);
points1[t * 3 + 2] = (float)(center.Z + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Z + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Z);
points2[t * 3] = (float)(center2.X + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.X + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.X);
points2[t * 3 + 1] = (float)(center2.Y + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Y + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Y);
points2[t * 3 + 2] = (float)(center2.Z + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Z + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Z);
indexs1[t] = t;
indexs2[t] = t;
if (t % 90 == 0)
{
points3[i * 3] = points1[t * 3];
points3[i * 3 + 1] = points1[t * 3 + 1];
points3[i * 3 + 2] = points1[t * 3 + 2];
points3[12 + i * 3] = points2[t * 3];
points3[12 + i * 3 + 1] = points2[t * 3 + 1];
points3[12 + i * 3 + 2] = points2[t * 3 + 2];
i++;
}
}
indexs1[pointcount] = 0;
indexs2[pointcount] = 0;
int[] indexs3 = new int[8] { 0, 4, 1, 5, 2, 6, 3, 7 };
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points1, indexs1, color, false);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points2, indexs2, color, false);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points3, indexs3, color, false);
}
//畫一個四棱錐
public static void RenderPyramid(Vector3F center, Vector3F normal, float height, float[] color, ClientBridge.ClientRenderSys rendersys)
{
if (normal.GetLength() != 0)
normal.Normalize();
else
return;
Vector3F top = GetPointDisNToPoint(center, normal, height);
Vector3F up = Tool.FloatCompare(normal.X, 0, float.Epsilon) && Tool.FloatCompare(normal.Y, 0, float.Epsilon) ? Vector3F.YAxis : Vector3F.ZAxis;
Vector3F right = Vector3F.CrossProduct(up, normal);
right.Normalize();
up = Vector3F.CrossProduct(right, normal);
up.Normalize();
float half_l = height / 5;
Vector3F[] verts = new Vector3F[6];
verts[0] = top;
verts[1] = center - half_l * right;
verts[2] = center - half_l * up;
verts[3] = center + half_l * right;
verts[4] = center + half_l * up;
verts[5] = center;
float[] points = new float[18];
for (int i = 0; i < 6; i++)
{
points[i * 3 + 0] = verts[i].X;
points[i * 3 + 1] = verts[i].Y;
points[i * 3 + 2] = verts[i].Z;
}
int[] indexs = new int[24] { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 1, 5, 2, 2, 5, 3, 3, 5, 4, 4, 5, 1 };
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_TRIANGLE_LIST, points, indexs, color, true);
}
public static void RenderConic(int shape, Vector3F center, Vector3F normal, float angle, float length, float[] color, ClientBridge.ClientRenderSys rendersys)
{
if (normal.GetLength() != 0)
{
normal.Normalize();
}
Vector3F center2 = GetPointDisNToPoint(center, normal, length);
float radius = (float)Math.Tan(Math.PI * angle / (180 * 2)) * length;
if (shape == (int)LightShape.CIRCLE)
{
int pointcount = 360;
float[] points = new float[pointcount * 3];
int[] indexs = new int[pointcount + 1];
float[] points1 = new float[15];
int i = 0;
for (int t = 0; t < pointcount; t++)
{
float factor = 0;
Vector3F u = new Vector3F();
if (Math.Abs(normal.X) > Math.Abs(normal.Y))
{
factor = 1.0f / (float)Math.Sqrt(normal.X * normal.X + normal.Z * normal.Z);
u.X = -normal.Z * factor;
u.Y = 0;
u.Z = normal.X * factor;
}
else
{
factor = 1.0f / (float)Math.Sqrt(normal.Y * normal.Y + normal.Z * normal.Z);
u.X = 0;
u.Y = normal.Z * factor;
u.Z = -normal.Y * factor;
}
u.Normalize();
Vector3F v = Vector3F.CrossProduct(normal, u);
v.Normalize();
points[t * 3] = (float)(center2.X + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.X + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.X);
points[t * 3 + 1] = (float)(center2.Y + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Y + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Y);
points[t * 3 + 2] = (float)(center2.Z + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Z + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Z);
indexs[t] = t;
if (t % 90 == 0)
{
points1[i * 3] = points[t * 3];
points1[i * 3 + 1] = points[t * 3 + 1];
points1[i * 3 + 2] = points[t * 3 + 2];
i++;
}
}
indexs[pointcount] = 0;
points1[12] = center.X;
points1[13] = center.Y;
points1[14] = center.Z;
int[] indexs1 = new int[8] { 4, 0, 4, 1, 4, 2, 4, 3 };
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs, color, false);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points1, indexs1, color, false);
}
else
{
float radius1 = radius * ((float)Math.Sqrt(2));
float[] points = new float[27];
for (int t = 0; t < 4; t++)
{
float factor = 0;
Vector3F u = new Vector3F();
if (Math.Abs(normal.X) > Math.Abs(normal.Y))
{
factor = 1.0f / (float)Math.Sqrt(normal.X * normal.X + normal.Z * normal.Z);
u.X = -normal.Z * factor;
u.Y = 0;
u.Z = normal.X * factor;
}
else
{
factor = 1.0f / (float)Math.Sqrt(normal.Y * normal.Y + normal.Z * normal.Z);
u.X = 0;
u.Y = normal.Z * factor;
u.Z = -normal.Y * factor;
}
u.Normalize();
Vector3F v = Vector3F.CrossProduct(normal, u);
v.Normalize();
points[t * 3] = (float)(center2.X + (radius1 * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.X + (radius1 * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.X);
points[t * 3 + 1] = (float)(center2.Y + (radius1 * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.Y + (radius1 * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.Y);
points[t * 3 + 2] = (float)(center2.Z + (radius1 * Math.Cos(Math.PI * (t * 90 + 45) / 180.0f)) * u.Z + (radius1 * Math.Sin(Math.PI * (t * 90 + 45) / 180.0f)) * v.Z);
points[12 + t * 3] = (float)(center2.X + (radius * Math.Cos(Math.PI * (t * 90) / 180.0f)) * u.X + (radius * Math.Sin(Math.PI * (t * 90) / 180.0f)) * v.X);
points[12 + t * 3 + 1] = (float)(center2.Y + (radius * Math.Cos(Math.PI * (t * 90) / 180.0f)) * u.Y + (radius * Math.Sin(Math.PI * (t * 90) / 180.0f)) * v.Y);
points[12 + t * 3 + 2] = (float)(center2.Z + (radius * Math.Cos(Math.PI * (t * 90) / 180.0f)) * u.Z + (radius * Math.Sin(Math.PI * (t * 90) / 180.0f)) * v.Z);
}
points[24] = center.X;
points[25] = center.Y;
points[26] = center.Z;
int[] indexs = new int[24] { 0, 1, 1, 2, 2, 3, 3, 0, 8, 0, 8, 1, 8, 2, 8, 3, 8, 4, 8, 5, 8, 6, 8, 7 };
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexs, color, false);
}
}
public static void RenderDirStartPoint(Vector3F start, Vector3F end, float radius, float[] color, IView view)
{
Vector3F dir = ComputeVectorAndNormalize(start, end);
radius = GetFakeLength(start, radius, stdDist, view);
RenderCloumn(start, dir, radius, 2 * radius, color, view.getRenderSys());
}
public static void RenderPrmStartPoint(int shape, Vector3F start, Vector3F end, float angle, float[] color, IView view)
{
Vector3F dir = ComputeVectorAndNormalize(start, end);
float length = GetFakeLength(start, 2, stdDist, view);
length = (float)(length * Math.Cos(Math.PI * angle / 360.0f));
RenderConic(shape, start, dir, angle, length, color, view.getRenderSys());
}
public static void RenderLightEndPoint(Vector3F start, Vector3F end, float radius, float[] color, IView view, bool hardsel)
{
Vector3F dir = ComputeVectorAndNormalize(start, end);
radius = GetFakeLength(end, radius, stdDist, view);
RenderCube(end, Vector3F.Negate(dir), radius, 2 * radius, color, view.getRenderSys(), hardsel);
}
}
// Group資訊
public struct GroupActorInfo
{
public string m_group_name; // 物品名稱 字首+id
public float m_height;
public bool m_bClose;
public RotateMode m_eRotateMode;
public GroupActorInfo(Dictionary<string, string> createpropdic, int curindex)
{
string nameprefix = createpropdic["NamePrefix"];
m_group_name = nameprefix + "_" + curindex.ToString();
try
{
m_height = float.Parse(createpropdic["Height"]);
}
catch (Exception)
{
m_height = 0;
}
m_bClose = true;
m_eRotateMode = RotateMode.RM_WHOLE;
}
// 轉換成屬性清單
public void toDic(Dictionary<string, string> dic)
{
dic["Name"] = m_group_name;
dic["Height"] = m_height.ToString();
dic["Close"] = m_bClose.ToString();
dic["RotateMode"] = m_eRotateMode.ToString();
}
public void valueChanged(string key, string value)
{
switch (key)
{
case "Name":
m_group_name = value;
break;
case "Height":
try
{
m_height = float.Parse(value);
}
catch (Exception)
{
m_height = 0;
}
break;
case "Close":
m_bClose = value.ToLower() == "true" ? true : false;
break;
case "RotateMode":
// fixme :
if (value == "RM_WHOLE")
m_eRotateMode = RotateMode.RM_WHOLE;
else if (value == "RM_SELF")
m_eRotateMode = RotateMode.RM_SELF;
else
m_eRotateMode = RotateMode.RM_BOTH;
break;
default:
break;
}
}
}
// Group
public class GroupActor : ActorBase, IActor
{
IActorLayerMng m_actor_layer = null;
GroupActorInfo m_actor_info;
// 包圍盒12條線段對應的GIID,在Group生成時就記錄下來。為解決打開Group時的選擇問題
GIID m_aabb_giid;
public GroupActor(GIIDMng giidmng, Dictionary<string, string> createpropdic, int curindex)
: this(giidmng, createpropdic, curindex, null)
{
}
public GroupActor(GIIDMng giidmng, Dictionary<string, string> createpropdic, int curindex, IActorLayerMng parentLayer)
: base(giidmng)
{
m_actor_info = new GroupActorInfo(createpropdic, curindex);
// 将m_actor_layer置為parentLayer類型
m_actor_layer = new ActorLayerMngImp(null, new DummyActorFun(), new DummyActorFun());
this.parentLayer = parentLayer;
//insertActors(ab);
//m_actor_layer.getOrgBuffer().add(ab);
// 位置
Vector3F max = GActorHelper.getMaxPos(m_actor_layer.getOrgBuffer());
Vector3F pos = GActorHelper.getMinPos(m_actor_layer.getOrgBuffer());
pos = new Vector3F((max.X + pos.X) / 2.0f, (max.Y + pos.Y) / 2.0f, 0);
locationmat = TransformationF.Translation(pos) * Matrix4F.Identity;
m_aabb_giid = giidmng.getGIID();
}
public GroupActor(GIIDMng giidmng, Dictionary<string, string> createpropdic, ActorBuffer ab, int curindex)
: base(giidmng)
{
m_actor_info = new GroupActorInfo(createpropdic, curindex);
m_actor_layer = new ActorLayerMngImp(null, new DummyActorFun(), new DummyActorFun());
m_actor_layer.getOrgBuffer().add(ab);
// 位置
Vector3F pos = GActorHelper.getMinPos(m_actor_layer.getOrgBuffer());
locationmat = TransformationF.Translation(pos) * Matrix4F.Identity;
m_aabb_giid = giidmng.getGIID();
}
public GroupActor(GIIDMng giidmng)
: base(giidmng)
{
m_actor_info = new GroupActorInfo();
m_actor_layer = new ActorLayerMngImp(null, new DummyActorFun(), new DummyActorFun());
m_aabb_giid = giidmng.getGIID();
}
public override ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_GROUP;
}
public void getSelectByID(Dictionary<IActorLayerMng, ActorBuffer> selactors, int id, IActorLayerMng sellayer)
{
if (m_aabb_giid.value == id)
{
// 得到應該被選中的Actor
IActor selactor = this;
if (!selactors.ContainsKey(sellayer))
{
selactors[sellayer] = new ActorBuffer(null, new DummyActorFun());
}
if (!selactors[sellayer].Contains<IActor>(selactor))
{
selactors[sellayer].insert(selactor);
}
}
foreach (IActor actor in getActorBuffer().getOrgBuffer())
{
if (actor is GroupActor)
{
((GroupActor)actor).getSelectByID(selactors, id, sellayer);
}
else if (actor.giid.value == id)
{
// 得到應該被選中的Actor
IActor selactor = actor;
while (selactor.parent != null && ((GroupActor)(selactor.parent)).close)
{
selactor = selactor.parent;
}
if (!selactors.ContainsKey(sellayer))
{
selactors[sellayer] = new ActorBuffer(null, new DummyActorFun());
}
if (!selactors[sellayer].Contains<IActor>(selactor))
{
selactors[sellayer].insert(selactor);
}
return;
}
}
}
//public void getSelectMoveLineID(int id, IActorLayerMng sellayer)
//{
//}
public override void pushHardwareSelect(ClientBridge.ClientRenderSys rendersys)
{
// 使所有子物品參與硬體選擇
getActorBuffer().pushHardwareSelect(rendersys);
if (!close)
{ // Group打開狀态下,包圍盒參與選擇
rendersys.pushSelectID((uint)(m_aabb_giid.value));
float[] c = { 1, 0, 0, 1 };
Vector3F[] vetexs = aabb.ComputeVertices();
float[] points = new float[24];
for (int i = 0; i < 8; i++)
{
points[i * 3] = vetexs[i].X;
points[i * 3 + 1] = vetexs[i].Y;
points[i * 3 + 2] = vetexs[i].Z;
}
int[] indexs = { 0,1, 1,2, 2,3, 3,0,
4,5, 5,6, 6,7, 7,4,
0,4, 1,5, 2,6, 3,7
};
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexs, c, false);
// fixme : 線的硬體選擇engine還有問題。。。
rendersys.pushSelectID(100);
rendersys.drawLine(vetexs[7].X, vetexs[7].Y, vetexs[7].Z, vetexs[0].X, vetexs[0].Y, vetexs[0].Z, c);
}
}
public override bool hide
{
get
{
return base.hide;
}
set
{
base.hide = value;
foreach (IActor actor in getActorBuffer().getOrgBuffer())
{
actor.hide = value;
}
}
}
public override bool freeze
{
get
{
return base.freeze;
}
set
{
base.freeze = value;
foreach (IActor actor in getActorBuffer().getOrgBuffer())
{
actor.freeze = value;
}
}
}
// Group關閉狀态
public bool close
{
get
{
return m_actor_info.m_bClose;
}
set
{
if (this is PrefebActor)
{
MessageBox.Show("fixme : can not open prefeb!");
return;
}
m_actor_info.m_bClose = value;
}
}
public override string name
{
get
{
return m_actor_info.m_group_name;
}
set
{
AssertUtil.confirm(this is PrefebActor);
m_actor_info.m_group_name = value;
}
}
public RotateMode rotatemode
{
get
{
return m_actor_info.m_eRotateMode;
}
set
{
m_actor_info.m_eRotateMode = value;
}
}
public void Dispose()
{
m_actor_layer.Dispose();
}
#region about IActor
public override IActorLayerMng getActorBuffer()
{
return m_actor_layer;
}
public List<T> getActors<T>() where T : IActor
{
List<T> l = new List<T>();
IEnumerator<T> it = m_actor_layer.getOrgBuffer().GetEnumerator<T>();
while (it.MoveNext())
{
l.Add(it.Current);
}
IEnumerator<GroupActor> it_group = m_actor_layer.getOrgBuffer().GetEnumerator<GroupActor>();
while (it_group.MoveNext())
{
l.AddRange(it_group.Current.getActors<T>());
}
return l;
}
public IActor clone(IEditItem edititem)
{
RootEditItem root = (RootEditItem)SceneGraph.getEditItemCommon("RootItem", edititem);
GroupActor actor = null;
return actor;
}
//public IMemento getMemento(int mode)
//{
// return null;
//}
//public void setMemento(IMemento mem)
//{
//}
public override bool serialize(BinaryWriter binWriter)
{
if (!(this is PrefebActor))
{
binWriter.Write(m_actor_info.m_group_name);
binWriter.Write(m_actor_info.m_height);
binWriter.Write(m_actor_info.m_bClose);
getActorBuffer().serialize(binWriter);
}
return base.serialize(binWriter);
}
public override bool serialize(BinaryReader binReader, IEditItem edititem)
{
if (!(this is PrefebActor))
{
m_actor_info.m_group_name = binReader.ReadString();
m_actor_info.m_height = binReader.ReadSingle();
m_actor_info.m_bClose = binReader.ReadBoolean();
m_actor_layer.serialize(binReader, edititem);
}
foreach (IActor actor in m_actor_layer.getOrgBuffer())
{
actor.parent = this;
}
return base.serialize(binReader, edititem);
}
#endregion
public override void render(int t, ClientBridge.ClientRenderSys rendersys)
{
// 調用自己的繪制函數
m_actor_layer.render(t, rendersys);
}
public override void renderAABB(int t, ClientBridge.ClientRenderSys rendersys, Color color)
{
base.renderAABB(t, rendersys, color);
}
public override IDictionary<string, string> getPropertyList()
{
m_actor_info.toDic(m_property_dic);
return base.getPropertyList();
}
public override void updateLocationAABB()
{
if (m_actor_layer.getOrgBuffer().Count<IActor>() == 0)
{
return;
}
// 修改包圍盒
IActor actor0 = m_actor_layer.getOrgBuffer().ElementAt<IActor>(0);
aabb = actor0.aabb;
foreach (IActor actor in m_actor_layer.getOrgBuffer())
{
Vector3F aabbmin = aabb.Min;
Vector3F aabbmax = aabb.Max;
if (actor.aabb.Min.X < aabbmin.X)
{
aabbmin.X = actor.aabb.Min.X;
}
if (actor.aabb.Min.Y < aabbmin.Y)
{
aabbmin.Y = actor.aabb.Min.Y;
}
if (actor.aabb.Min.Z < aabbmin.Z)
{
aabbmin.Z = actor.aabb.Min.Z;
}
if (actor.aabb.Max.X > aabbmax.X)
{
aabbmax.X = actor.aabb.Max.X;
}
if (actor.aabb.Max.Y > aabbmax.Y)
{
aabbmax.Y = actor.aabb.Max.Y;
}
if (actor.aabb.Max.Z > aabbmax.Z)
{
aabbmax.Z = actor.aabb.Max.Z;
}
aabb = new AxisAlignedBox(aabbmin, aabbmax);
}
base.updateLocationAABB();
}
public override void notifyPropertyChange(String key, String value)
{
base.notifyPropertyChange(key, value);
m_actor_info.valueChanged(key, value);
}
}
public struct PrefebActorInfo
{
public string m_group_name;
public string m_prefeb_name;
public PrefebActorInfo(string group, string name)
{
m_group_name = group;
m_prefeb_name = name;
}
}
// 包裹
public class PrefebActor : GroupActor
{
public PrefebActor(GIIDMng giidmng, Dictionary<string, string> createpropdic, ActorBuffer ab, int curindex, string group, string name)
: base(giidmng, createpropdic, ab, curindex)
{
m_prefeb_info = new PrefebActorInfo(group, name);
}
public PrefebActor(GIIDMng giidmng)
: base(giidmng)
{
m_prefeb_info = new PrefebActorInfo();
}
public override IDictionary<string, string> getPropertyList()
{
return base.getPropertyList();
}
// 判斷包裹執行個體是否由某個包裹模闆建立
public bool isCreateFrom(string groupname, string prefebname)
{
return ((m_prefeb_info.m_group_name == groupname) && (m_prefeb_info.m_prefeb_name == prefebname));
}
public override bool serialize(BinaryWriter binWriter)
{
binWriter.Write(m_prefeb_info.m_group_name);
binWriter.Write(m_prefeb_info.m_prefeb_name);
return base.serialize(binWriter);
}
public override bool serialize(BinaryReader binReader, IEditItem edititem)
{
return base.serialize(binReader, edititem);
}
PrefebActorInfo m_prefeb_info;
}
// 包裹管理器
public class PrefebManager
{
public static void allrotateandmove(GroupActor actor, Matrix4F rotatemat)
{
actor.moveTo(new Vector3F(0, 0, 0));
IActorLayerMng sublayer = actor.getActorBuffer();
foreach (IActor subactor in sublayer.getOrgBuffer())
{
if (subactor is GroupActor)
allrotateandmove((GroupActor)subactor, rotatemat * new Matrix4F(subactor.locationmat));
else
subactor.notifyPropertyChange("LocationMat", (rotatemat * subactor.locationmat).ToString());
}
actor.notifyPropertyChange("LocationMat", (rotatemat * actor.locationmat).ToString());
}
// 将指定物品生成Prefeb模闆檔案。groupname:組名; name:包裹名稱
public static void generatePrefebFile(IActorLayerMng layer, ActorBuffer ab, string groupname, string prefebname)
{
bool prefebmodifyflag = false;
string path = s_xml_path_prefix + "/" + groupname;
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string fullfilename = path + "/" + prefebname + ".xml";
if (File.Exists(fullfilename))
{
DialogResult dr = MessageBox.Show("名為[" + prefebname + "]的包裹已存在,是否覆寫?覆寫将更新所有對應的包裹執行個體!", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (dr == DialogResult.Yes)
{
prefebmodifyflag = true;
}
else if (dr == DialogResult.No)
{
generatePrefebFile(layer, ab, groupname, prefebname + " new");
return;
}
}
XmlDocument xml = new XmlDocument();
XmlDeclaration xmldecl;
xmldecl = xml.CreateXmlDeclaration("1.0", "GBK", "yes");
xml.AppendChild(xmldecl);
XmlNode rootElem = xml.CreateNode("element", "PrefebActor", "");
xml.AppendChild(rootElem);
XmlNode propertynode;
// fixme : 包裹資訊,暫時在程式中寫死
propertynode = xml.CreateNode("element", "NamePrefix", "");
propertynode.InnerText = prefebname;
rootElem.InsertAfter(propertynode, rootElem.LastChild);
propertynode = xml.CreateNode("element", "Height", "");
propertynode.InnerText = "0";
rootElem.InsertAfter(propertynode, rootElem.LastChild);
// 儲存包裹中物品的資訊,,,
XmlNode actornode;
XmlAttribute actoratt;
foreach (IActor actor in ab)
{
actornode = xml.CreateNode("element", "Item", "");
actoratt = xml.CreateAttribute("type");
actoratt.Value = GActorHelper.getActorTypestr(actor);
actornode.Attributes.Append(actoratt);
actor.serialize(actornode, null, false, false);
rootElem.InsertAfter(actornode, rootElem.LastChild);
}
xml.Save(fullfilename);
if (prefebmodifyflag)
{
GActorHelper.updatePrefebActors(layer, groupname, prefebname);
}
return;
}
// 包裹内容的擷取
public static PrefebActor getActorBufferFromPrefebFile(string groupname, string name, IEditItem edititem)
{
ActorBuffer ab = new ActorBuffer(null, new DummyActorFun());
Dictionary<string, string> createpropdic = new Dictionary<string, string>();
//
XmlDocument prefebxml = new XmlDocument();
string filename = s_xml_path_prefix + "/" + groupname + "/" + name + ".xml";
prefebxml.Load(filename);
foreach (XmlNode childnode in prefebxml.SelectSingleNode("PrefebActor").ChildNodes)
{
if (childnode.Name != "Item")
{
// to get the prefeb properties
createpropdic[childnode.Name] = childnode.InnerText;
}
else
{
// to get the properties of the child actors
XmlAttribute typeatt = childnode.Attributes["type"];
IActor actor = GActorHelper.generateActorWithoutInfo(typeatt.Value, edititem);
actor.serialize(childnode, edititem, true, false);
ab.insert(actor);
}
}
RootEditItem root = (RootEditItem)(SceneGraph.getEditItemCommon("RootItem", edititem));
IDocFactory df = (IDocFactory)SceneGraph.getEditItemCommon("DocFactory", (IEditItem)SceneGraph.getEditItemCommon("RootItem", edititem));
IDoc doc = (IDoc)SceneGraph.getEditItemCommon("doc", df);
string prefix = createpropdic["NamePrefix"];
PrefebActor prefebactor = new PrefebActor(root.giidmng, createpropdic, ab, doc.getMaxActorIndex(prefix), groupname, name);
foreach (IActor actor in ab)
{
actor.parent = prefebactor;
}
return prefebactor;
}
// Prefeb模闆xml所在路徑
private static string s_xml_path_prefix = @"../resources/editor/Prefebs";
}
// 物品memento,用物品屬性清單建構
public class DancerMemento : IMemento
{
public Dictionary<String, String> m_property_dic = new Dictionary<string, string>();
public int m_index;
public float m_angle;
public bool m_ismale;
public List<string> m_bodyparts = new List<string>();
public string m_act = "";
}
// 人物 fixme:僅做了一個給美術臨時用的測試版本,不能儲存讀取
public class DancerActor : ActorBase, IActor
{
public int m_index;
public float m_angle;
public bool m_ismale;
public List<string> m_bodyparts = new List<string>();
public string m_act = "";
public string m_name;
public DancerActor(GIIDMng giidmng, ClientBridge.ClientRenderSys rendersys)
: base(giidmng)
{
}
public DancerActor(GIIDMng giidmng, string name, bool ismale, int index, ClientBridge.ClientRenderSys rendersys)
: base(giidmng)
{
m_name = name;
m_index = index;
m_ismale = ismale;
// 設定預設值
m_angle = 90;
m_bodyparts.Add("100000004.bp3");
m_bodyparts.Add("101001004.bp3");
m_bodyparts.Add("102004001.bp3");
m_bodyparts.Add("103021002.bp3");
m_bodyparts.Add("104025001.bp3");
m_bodyparts.Add("105000000.bp3");
m_bodyparts.Add("106008001.bp3");
m_bodyparts.Add("107000000.bp3");
m_bodyparts.Add("108010001.bp3");
}
public override ACTOR_TYPE GetActorType()
{
return ACTOR_TYPE.AT_ACTOR;
}
public void Dispose()
{
m_bodyparts.Clear();
}
#region about IActor
public IActor clone(IEditItem edititem)
{
RootEditItem root = (RootEditItem)SceneGraph.getEditItemCommon("RootItem", edititem);
DancerActor actor = null;
return actor;
}
public override void render(int t, ClientBridge.ClientRenderSys rendersys)
{
}
public override void renderAABB(int t, ClientBridge.ClientRenderSys rendersys, Color color)
{
base.renderAABB(t, rendersys, color);
}
#endregion
public override IDictionary<string, string> getPropertyList()
{
return base.getPropertyList();
}
public override void notifyPropertyChange(String key, String value)
{
base.notifyPropertyChange(key, value);
}
// 獲得物品Memento
public override IMemento getMemento(int mode)
{
DancerMemento mem = new DancerMemento();
foreach (KeyValuePair<string, string> kv in m_property_dic)
{
mem.m_property_dic.Add(kv.Key, kv.Value);
}
mem.m_act = m_act;
mem.m_angle = m_angle;
foreach (string str in m_bodyparts)
{
mem.m_bodyparts.Add(str);
}
mem.m_index = m_index;
mem.m_ismale = m_ismale;
return mem;
}
// 設定物品Memento
public override void setMemento(IMemento mem)
{
DancerMemento actormem = (DancerMemento)mem;
m_act = actormem.m_act;
m_angle = actormem.m_angle;
m_bodyparts.Clear();
foreach (string str in actormem.m_bodyparts)
{
m_bodyparts.Add(str);
}
m_index = actormem.m_index;
m_ismale = actormem.m_ismale;
foreach (KeyValuePair<string, string> kv in actormem.m_property_dic)
{
notifyPropertyChange(kv.Key, kv.Value);
}
updateLocationAABB();
}
}
// -------------
// 在物品加入容器或從容器中移出時,會調用相應的函數
public interface IActorFun
{
void insert(IActor actor, IActorLayerMng layer);
void remove(IActor actor, IActorLayerMng layer);
}
// 在物品加入容器或從容器中移出時,不做任何事情
public class DummyActorFun : IActorFun
{
#region IActorFun 成員
public void insert(IActor actor, IActorLayerMng layer)
{
}
public void remove(IActor actor, IActorLayerMng layer)
{
}
#endregion
}
// 在删除以及插入actor時,将actor的層次管理器(如果有的話)删除或添加到對應的層次管理器中
public class ActorAsLayerActorFun : IActorFun
{
public void insert(IActor actor, IActorLayerMng layer)
{
if (actor.getActorBuffer() != null)
{
layer.getList().Add(actor.getActorBuffer());
actor.getActorBuffer().parent = layer;
}
}
public void remove(IActor actor, IActorLayerMng layer)
{
if (actor.getActorBuffer() != null)
{
actor.getActorBuffer().parent = null;
layer.getList().Remove(actor.getActorBuffer());
}
}
}
// 物品容器,用來記錄相同類型和不同類型的物品,可以輪訓
// 不負責所記錄actor的銷毀
// public class ActorBuffer : IEnumerable<IActor>
// {
// // 所在的物品層
// IActorLayerMng m_layer;
// // 物品移入移出時所調用的函數
// IActorFun m_actor_fun;
//
// public ActorBuffer(IActorLayerMng layer, IActorFun fun)
// {
// m_layer = layer;
// m_actor_fun = fun;
// }
// // 物品容器用來記錄所有的物品,不同類型還沒有用不同的容器來儲存
// Dictionary<Type, Dictionary<IActor, IActor>> m_dic = new Dictionary<Type, Dictionary<IActor, IActor>>();
//
// // 疊代器供疊代使用,将Dictionary的疊代器轉化為IEnumerator<IActor>類型的疊代器
// // fixme: 可以為了針對指定類型的疊代,這個類還需要記錄所剩物品類型所對應的物品容器
// public class ActorBufferEnumerator<T> : IEnumerator<T> where T: IActor
// {
// public ActorBufferEnumerator(IEnumerator<KeyValuePair<Type, Dictionary<IActor, IActor>>> base_enumerator)
// {
// AssertUtil.confirm(base_enumerator != null);
// m_base_enumerator = base_enumerator;
// Reset();
// }
// public ActorBufferEnumerator(IEnumerator<KeyValuePair<IActor, IActor>> cur_enumerator)
// {
// m_cur_enumerator = cur_enumerator;
// m_single_type = true;
// }
//
// IEnumerator<KeyValuePair<Type, Dictionary<IActor, IActor>>> m_base_enumerator;
// IEnumerator<KeyValuePair<IActor, IActor>> m_cur_enumerator;
// bool m_single_type = false;
//
// public T Current
// {
// get { return (T)m_cur_enumerator.Current.Key; }
// }
//
// public void Dispose()
// {
// if (m_base_enumerator != null)
// {
// m_base_enumerator.Dispose();
// }
// if (m_cur_enumerator != null)
// {
// m_cur_enumerator.Dispose();
// }
// }
//
// object System.Collections.IEnumerator.Current
// {
// get { return m_cur_enumerator.Current.Key; }
// }
//
// public bool MoveNext()
// {
// if (m_cur_enumerator == null)
// {
// return false;
// }
// if (m_cur_enumerator.MoveNext())
// {
// return true;
// }
// else
// {
// if (!m_single_type && m_base_enumerator.MoveNext())
// {
// m_cur_enumerator = m_base_enumerator.Current.Value.GetEnumerator();
//
// return MoveNext();
// }
// else
// {
// return false;
// }
// }
// }
//
// public void Reset()
// {
// if (m_single_type && m_cur_enumerator != null)
// {
// m_cur_enumerator.Reset();
// }
// else
// {
// m_base_enumerator.Reset();
// if (m_base_enumerator.MoveNext())
// {
// m_cur_enumerator = m_base_enumerator.Current.Value.GetEnumerator();
// }
// else
// {
// m_cur_enumerator = null;
// }
// }
// }
// }
//
// // 是否沒有内容
// public bool empty()
// {
// return m_dic.Count == 0;
// }
// //
// public void insert(IActor a)
// {
// if (!m_dic.ContainsKey(a.GetType()))
// {
// m_dic.Add(a.GetType(), new Dictionary<IActor, IActor>());
// }
// m_dic[a.GetType()].Add(a, a);
// m_actor_fun.insert(a, m_layer);
// }
// //
// public void remove(IActor a)
// {
// if (m_dic.ContainsKey(a.GetType()))
// {
// m_dic[a.GetType()].Remove(a);
// m_actor_fun.remove(a, m_layer);
// if (m_dic[a.GetType()].Count == 0)
// {
// m_dic.Remove(a.GetType());
// }
// }
// }
// // 清除所有内容
// // 本類不負責所記錄actor的銷毀
// public void clear()
// {
// m_dic.Clear();
// }
// // 集合減操作,修改自身内容
// public void substract(ActorBuffer buf)
// {
// foreach (KeyValuePair<Type, Dictionary<IActor, IActor>> tvp in buf.m_dic)
// {
// if (m_dic.ContainsKey(tvp.Key))
// {
// foreach (KeyValuePair<IActor, IActor> kvp in tvp.Value)
// {
// if (m_dic[tvp.Key].ContainsKey(kvp.Key))
// {
// m_dic[tvp.Key].Remove(kvp.Key);
// m_actor_fun.remove(kvp.Key, m_layer);
// }
// }
// if (m_dic[tvp.Key].Count == 0)
// {
// m_dic.Remove(tvp.Key);
// }
// }
// }
// }
// // 集合并操作,修改自身内容
// public void add(ActorBuffer buf)
// {
// foreach (KeyValuePair<Type, Dictionary<IActor, IActor>> tvp in buf.m_dic)
// {
// if (!m_dic.ContainsKey(tvp.Key))
// {
// m_dic.Add(tvp.Key, new Dictionary<IActor, IActor>());
// }
// foreach (KeyValuePair<IActor, IActor> kvp in tvp.Value)
// {
// if (!m_dic[tvp.Key].ContainsKey(kvp.Key))
// {
// m_dic[tvp.Key].Add(kvp.Key, kvp.Value);
// m_actor_fun.insert(kvp.Key, m_layer);
// }
// }
// if (m_dic[tvp.Key].Count == 0)
// {
// m_dic.Remove(tvp.Key);
// }
// }
// }
// // 複制自身内容,注意不複制對應的IActorFun
// public ActorBuffer clone()
// {
// ActorBuffer actorbuf = new ActorBuffer(null, new DummyActorFun());
//
// actorbuf.add(this);
//
// return actorbuf;
// }
// // // 針對不同類型的疊代器
// // public IEnumerator<T> GetEnumerator<T>() where T : IActor
// // {
// // if (m_dic.ContainsKey(typeof(T)))
// // {
// // return new ActorBufferEnumerator<T>(m_dic[typeof(T)].GetEnumerator());
// // }
// // else
// // {
// // return new ActorBufferEnumerator<T>((IEnumerator<KeyValuePair<IActor, IActor>>)null);
// // }
// // }
// // //
// // public IEnumerator<IActor> GetEnumerator()
// // {
// // return new ActorBufferEnumerator<IActor>(m_dic.GetEnumerator());
// // }
// // //
// // System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
// // {
// // return new ActorBufferEnumerator<IActor>(m_dic.GetEnumerator());
// // }
//
// // 針對不同類型的疊代器
// public IEnumerator<T> GetEnumerator<T>() where T : IActor
// {
// return GetEnumerator<T>(false);
// }
// public IEnumerator<T> GetEnumerator<T>(bool recurse) where T : IActor
// {
// return new ActorBufferEnumerator<T>(recurse, false, m_actor_dic, m_type_dic);
// }
// public IEnumerator<T> GetReverseEnumerator<T>() where T : IActor
// {
// return GetReverseEnumerator<T>(false);
// }
// public IEnumerator<T> GetReverseEnumerator<T>(bool recurse) where T : IActor
// {
// return new ActorBufferEnumerator<T>(recurse, true, m_actor_dic, m_type_dic);
// }
// //
// public IEnumerator<IActor> GetEnumerator()
// {
// return new ActorBufferEnumerator<IActor>(true, false, m_actor_dic, m_type_dic);
// }
// //
// System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
// {
// return new ActorBufferEnumerator<IActor>(true, false, m_actor_dic, m_type_dic);
// }
//
// // 是否包含指定的物品
// public bool contain(IActor actor)
// {
// if (actor != null)
// {
// if (m_dic.ContainsKey(actor.GetType()))
// {
// return m_dic[actor.GetType()].ContainsKey(actor);
// }
// }
// return false;
// }
// }
// 物品容器,用來記錄相同類型和不同類型的物品,可以輪訓
// 不負責所記錄actor的銷毀
public class ActorBuffer : IEnumerable<IActor>
{
/// <summary>
/// 所在的物品層
/// </summary>
[XmlIgnore]
public IActorLayerMng LayerMng
{
get { return m_layer; }
set { m_layer = value; }
}
/// <summary>
/// 物品移入移出時所調用的函數
/// 序列化使用
/// </summary>
[XmlElement]
public IActorFun ActorFun
{
get { return m_actor_fun; }
set { m_actor_fun = value; }
}
//判斷内部類型是否是傳入類型或者是否是傳入類型的子類型
public ActorBuffer getTypeActors(Type _t)
{
ActorBuffer buffer = new ActorBuffer(m_layer, m_actor_fun);
foreach (Type type in m_actor_dic.Keys)
{
bool b = false; Type t = type;
while (t != null && !b)
if (t.Equals(_t))
b = true;
else
t = t.BaseType;
if (b)
foreach (IActor actor in m_actor_dic[type].Values)
buffer.insert(actor);
}
return buffer;
}
public ActorBuffer(IActorLayerMng layer, IActorFun fun)
{
m_layer = layer;
m_actor_fun = fun;
}
// 是否沒有内容
public bool empty()
{
return m_actor_dic.Count == 0;
}
//
public void insert(IActor a)
{
if (!m_actor_dic.ContainsKey(a.GetType()))
{
m_actor_dic.Add(a.GetType(), new Dictionary<GIID, IActor>());
addType(a.GetType());
}
if (!m_actor_dic[a.GetType()].ContainsKey(a.giid))
{
m_actor_dic[a.GetType()].Add(a.giid, a);
if (a.getActorBuffer() != null)
addChildren(a);
m_actor_fun.insert(a, m_layer);
//if (m_layer != null)
// a.parentLayer = m_layer;
}
}
//
public void remove(IActor a)
{
if (m_actor_dic.ContainsKey(a.GetType()))
{
m_actor_dic[a.GetType()].Remove(a.giid);
if (m_actor_dic[a.GetType()].Count == 0)
{
m_actor_dic.Remove(a.GetType());
removeType(a.GetType());
}
if (a.getActorBuffer() != null)
substractChildren(a);
m_actor_fun.remove(a, m_layer);
}
}
public IActor find(GIID giid)
{
foreach (KeyValuePair<Type, Dictionary<GIID, IActor>> pair in m_actor_dic)
{
if (pair.Value.ContainsKey(giid))
{
return pair.Value[giid];
}
}
return null;
}
// 清除所有内容
// 本類不負責所記錄actor的銷毀
public void clear()
{
List<IActor> romove_list = new List<IActor>();
foreach (KeyValuePair<Type, Dictionary<GIID, IActor>> tvp in m_actor_dic)
{
foreach (KeyValuePair<GIID, IActor> kvp in tvp.Value)
{
romove_list.Add(kvp.Value);
}
}
m_actor_dic.Clear();
m_type_dic.Clear();
foreach (IActor actor in romove_list)
{
m_actor_fun.remove(actor, m_layer);
}
}
// 集合減操作,修改自身内容
public void substract(ActorBuffer buf)
{
List<IActor> romove_list = new List<IActor>();
foreach (KeyValuePair<Type, Dictionary<GIID, IActor>> tvp in buf.m_actor_dic)
{
if (m_actor_dic.ContainsKey(tvp.Key))
{
Dictionary<GIID, IActor> actors = m_actor_dic[tvp.Key];
foreach (KeyValuePair<GIID, IActor> kvp in tvp.Value)
{
if (actors.ContainsKey(kvp.Key))
{
actors.Remove(kvp.Key);
romove_list.Add(kvp.Value);
}
}
if (actors.Count == 0)
{
m_actor_dic.Remove(tvp.Key);
removeType(tvp.Key);
}
}
}
foreach (IActor actor in romove_list)
{
if (actor.getActorBuffer() != null)
substractChildren(actor);
//actor.DoBeforeDel();
m_actor_fun.remove(actor, m_layer);
}
}
private void substractChildren(IActor actor)
{
foreach (IActor childActor in actor.getActorBuffer().getOrgBuffer())
{
if (childActor.getActorBuffer() != null)
substractChildren(childActor);
m_actor_fun.remove(childActor, m_layer);
}
}
// 集合并操作,修改自身内容
public void add(ActorBuffer buf)
{
foreach (KeyValuePair<Type, Dictionary<GIID, IActor>> tvp in buf.m_actor_dic)
{
if (!m_actor_dic.ContainsKey(tvp.Key))
{
m_actor_dic.Add(tvp.Key, new Dictionary<GIID, IActor>());
addType(tvp.Key);
}
Dictionary<GIID, IActor> actors = m_actor_dic[tvp.Key];
foreach (KeyValuePair<GIID, IActor> kvp in tvp.Value)
{
if (!actors.ContainsKey(kvp.Key))
{
actors.Add(kvp.Key, kvp.Value);
if (kvp.Value.getActorBuffer() != null)
addChildren(kvp.Value);
m_actor_fun.insert(kvp.Value, m_layer);
//if (m_layer != null)
// kvp.Value.parentLayer = m_layer;
}
}
}
}
private void addChildren(IActor actor)
{
foreach (IActor childActor in actor.getActorBuffer().getOrgBuffer())
{
if (childActor.getActorBuffer() != null)
addChildren(childActor);
m_actor_fun.insert(childActor, m_layer);
childActor.parentLayer = actor.getActorBuffer();
}
}
// 複制自身内容,注意不複制對應的IActorFun
public ActorBuffer clone()
{
ActorBuffer actorbuf = new ActorBuffer(null, new DummyActorFun());
actorbuf.add(this);
return actorbuf;
}
// 針對不同類型的疊代器
public IEnumerator<T> GetEnumerator<T>() where T : IActor
{
return GetEnumerator<T>(false);
}
public IEnumerator<T> GetEnumerator<T>(bool recurse) where T : IActor
{
return new ActorBufferEnumerator<T>(recurse, false, m_actor_dic, m_type_dic);
}
public IEnumerator<T> GetReverseEnumerator<T>() where T : IActor
{
return GetReverseEnumerator<T>(false);
}
public IEnumerator<T> GetReverseEnumerator<T>(bool recurse) where T : IActor
{
return new ActorBufferEnumerator<T>(recurse, true, m_actor_dic, m_type_dic);
}
//
public IEnumerator<IActor> GetEnumerator()
{
return new ActorBufferEnumerator<IActor>(true, false, m_actor_dic, m_type_dic);
}
//
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return new ActorBufferEnumerator<IActor>(true, false, m_actor_dic, m_type_dic);
}
// 是否包含指定的物品
public bool contain(IActor actor)
{
if (actor != null)
{
if (m_actor_dic.ContainsKey(actor.GetType()))
{
return m_actor_dic[actor.GetType()].ContainsKey(actor.giid);
}
}
return false;
}
private void addType(Type type)
{
Type base_type = type.BaseType;
Type iactor_type = typeof(IActor);
if (iactor_type.IsAssignableFrom(base_type))
{
addType(base_type);
}
else
{
base_type = iactor_type;
}
if (!m_type_dic.ContainsKey(base_type))
{
m_type_dic.Add(base_type, new Dictionary<Type, Type>());
}
if (!m_type_dic[base_type].ContainsKey(type))
{
m_type_dic[base_type].Add(type, type);
}
}
private void removeType(Type type)
{
if (!m_type_dic.ContainsKey(type))
{
Type base_type = type.BaseType;
Type iactor_type = typeof(IActor);
if (!iactor_type.IsAssignableFrom(base_type))
{
base_type = iactor_type;
}
if (!m_type_dic.ContainsKey(type) && m_type_dic.ContainsKey(base_type))
{
m_type_dic[base_type].Remove(type);
if (m_type_dic[base_type].Count == 0)
{
m_type_dic.Remove(base_type);
}
}
}
}
/// <summary>
/// 擷取一個Actor,當隻有一個Actor存在時,這個Actor一般是根Actor
/// </summary>
/// <returns></returns>
public IActor getFirstActor()
{
foreach (KeyValuePair<Type, Dictionary<GIID, IActor>> pair in m_actor_dic)
{
foreach (KeyValuePair<GIID, IActor> p in pair.Value)
{
return p.Value;
}
}
return null;
}
// 疊代器供疊代使用,将Dictionary的疊代器轉化為IEnumerator<IActor>類型的疊代器
// fixme: 可以為了針對指定類型的疊代,這個類還需要記錄所剩物品類型所對應的物品容器
private class ActorBufferEnumerator<T> : IEnumerator<T> where T : IActor
{
public ActorBufferEnumerator(bool recurse, bool reverse, Dictionary<Type, Dictionary<GIID, IActor>> actor_dic, Dictionary<Type, Dictionary<Type, Type>> type_dic)
{
m_recurse = recurse;
m_reverse = reverse;
m_actor_dic = actor_dic;
m_type_dic = type_dic;
Reset();
}
public T Current
{
get { return (T)m_cur_enumerator.Current.Value; }
}
public void Dispose()
{
if (m_cur_enumerator != null)
{
m_cur_enumerator.Dispose();
}
}
object System.Collections.IEnumerator.Current
{
get { return m_cur_enumerator.Current.Key; }
}
public bool MoveNext()
{
if (m_cur_enumerator != null && m_cur_enumerator.MoveNext())
{
return true;
}
else
{
if (m_type_stack.Count > 0)
{
Type cur_type = m_type_stack[0];
m_type_stack.RemoveAt(0);
if (m_recurse && m_type_dic.ContainsKey(cur_type))
{
foreach (KeyValuePair<Type, Type> kvp in (m_reverse ? Enumerable.Reverse(m_type_dic[cur_type]) : m_type_dic[cur_type]))
{
m_type_stack.Add(kvp.Key);
}
}
if (m_actor_dic.ContainsKey(cur_type))
{
m_cur_enumerator = (m_reverse ? Enumerable.Reverse(m_actor_dic[cur_type]) : m_actor_dic[cur_type]).GetEnumerator();
}
return MoveNext();
}
else
{
return false;
}
}
}
public void Reset()
{
m_type_stack.Clear();
m_type_stack.Add(m_base_type);
m_cur_enumerator = null;
}
List<Type> m_type_stack = new List<Type>();
IEnumerator<KeyValuePair<GIID, IActor>> m_cur_enumerator;
Type m_base_type = typeof(T);
bool m_recurse = false;
bool m_reverse = false;
Dictionary<Type, Dictionary<GIID, IActor>> m_actor_dic;
Dictionary<Type, Dictionary<Type, Type>> m_type_dic;
}
// 所在的物品層
IActorLayerMng m_layer;
// 物品移入移出時所調用的函數
IActorFun m_actor_fun;
// 物品容器用來記錄所有的物品
Dictionary<Type, Dictionary<GIID, IActor>> m_actor_dic = new Dictionary<Type, Dictionary<GIID, IActor>>();
Dictionary<Type, Dictionary<Type, Type>> m_type_dic = new Dictionary<Type, Dictionary<Type, Type>>();
}
// Actor輔助類
public class GActorHelper
{
// 根據生成屬性生成指定類别物品
public static IActor generateActor(string type, Dictionary<string, string> createpropdic, IEditItem edititem)
{
RootEditItem root = (RootEditItem)(SceneGraph.getEditItemCommon("RootItem", edititem));
IDocFactory df = (IDocFactory)SceneGraph.getEditItemCommon("DocFactory", (IEditItem)SceneGraph.getEditItemCommon("RootItem", edititem));
IDoc doc = (IDoc)SceneGraph.getEditItemCommon("doc", df);
string prefix = (type != "DancerActor" && createpropdic.ContainsKey("NamePrefix")) ? createpropdic["NamePrefix"] : "dancer";
int actorindex = doc.getMaxActorIndex(prefix);
switch (type)
{
case "ModelActor":
return new ModelActor(root.giidmng, createpropdic, root.clientRenderSys, actorindex);
case "EffectActor":
return new EffectActor(root.giidmng, createpropdic, root.clientRenderSys, actorindex);
case "LightActor":
return new LightActor(root.giidmng, new LightInfo(), root.clientRenderSys);
case "AINodeActor":
return new AINodeActor(root.giidmng); // fixme :
case "SoundActor":
return new SoundActor(root.giidmng);
case "GroupActor":
return new GroupActor(root.giidmng);
case "PrefebActor":
return PrefebManager.getActorBufferFromPrefebFile(createpropdic["group"], createpropdic["name"], edititem);
case "DancerActor":
return new DancerActor(root.giidmng, "nametest", true, actorindex - 1, root.clientRenderSys);
default:
return null;
}
}
// 生成不含物品具體資訊的物品
public static IActor generateActorWithoutInfo(string type, IEditItem edititem)
{
RootEditItem root = (RootEditItem)(SceneGraph.getEditItemCommon("RootItem", edititem));
switch (type)
{
case "ModelActor":
return new ModelActor(root.giidmng);
case "EffectActor":
return new EffectActor(root.giidmng);
case "LightActor":
return new LightActor(root.giidmng);
case "AINodeActor":
return new AINodeActor(root.giidmng);
case "SoundActor":
return new SoundActor(root.giidmng);
case "GroupActor":
return new GroupActor(root.giidmng);
case "PrefebActor":
return new PrefebActor(root.giidmng);
default:
return null;
}
}
public static void getTypeActors(Dictionary<IActorLayerMng, ActorBuffer> resultactors, IActorLayerMng layer, string type, bool select, bool substract)
{
ActorBuffer allab = select ? (layer.getSelBuffer()) : (layer.getOrgBuffer());
foreach (IActor actor in allab)
{
if (getActorTypestr(actor) == type)
{
if (!resultactors.ContainsKey(layer))
{
resultactors[layer] = new ActorBuffer(null, new DummyActorFun());
}
resultactors[layer].insert(actor);
//ab.insert(actor);
}
}
if (substract)
{
foreach (IActor actor in allab)
{
if (getActorTypestr(actor) == type)
{
layer.getOrgBuffer().remove(actor);
}
}
}
foreach (IActorLayerMng sublayer in layer.getList())
{
getTypeActors(resultactors, sublayer, type, select, substract);
}
}
//得到指定層及其子層中的物品 unfreeze:為true則不擷取當機物體 DTK198 liaowenfang
public static void getActors(ActorBuffer ab, IActorLayerMng layer, bool select, bool substract, bool unfreeze)
{
ActorBuffer allab = select ? (layer.getSelBuffer()) : (layer.getOrgBuffer());
ab.add(allab);
if (substract)
{
layer.getOrgBuffer().substract(allab);
}
foreach (IActorLayerMng sublayer in layer.getList())
{
getActors(ab, sublayer, select, substract);
}
if (unfreeze)
{
ActorBuffer ufab = new ActorBuffer(ab.LayerMng, ab.ActorFun);
foreach (IActor actor in ab)
if (!actor.freeze && !actor.hide && !BaseCommand.isActorLayerReadOnly(actor.parentLayer, BaseCommand.ACTORLAYER_ITERATE_MODE.FREEZE | BaseCommand.ACTORLAYER_ITERATE_MODE.HIDE))
ufab.insert(actor);
ab.clear();
ab.add(ufab);
}
}
// 得到指定層及其子層中的物品,參數含義同getTypeActors
public static void getActors(ActorBuffer ab, IActorLayerMng layer, bool select, bool substract)
{
getActors(ab, layer, select, substract, false);
}
public static void updatePrefebActors(IActorLayerMng layer, string groupname, string prefebname)
{
ActorBuffer abold = new ActorBuffer(null, new DummyActorFun());
ActorBuffer abnew = new ActorBuffer(null, new DummyActorFun());
foreach (IActor actor in layer.getOrgBuffer())
{
if (actor is PrefebActor)
{
PrefebActor pactor = actor as PrefebActor;
if (pactor.isCreateFrom(groupname, prefebname))
{
abold.insert(actor);
IActor newactor = PrefebManager.getActorBufferFromPrefebFile(groupname, prefebname, layer);
// 位置更新
Vector3F posold = GActorHelper.getMinPos(actor.getActorBuffer().getOrgBuffer());
Vector3F posnew = GActorHelper.getMinPos(newactor.getActorBuffer().getOrgBuffer());
Vector3F posmove = posold - posnew;
foreach (IActor subactor in newactor.getActorBuffer().getOrgBuffer())
{
subactor.move(posmove);
}
abnew.insert(newactor);
}
}
}
layer.getOrgBuffer().substract(abold);
layer.getOrgBuffer().add(abnew);
foreach (IActorLayerMng sublayer in layer.getList())
{
updatePrefebActors(sublayer, groupname, prefebname);
}
}
// 得到物品類别字元串
public static string getActorTypestr(IActor actor)
{
if (actor is ModelActor)
{
return "ModelActor";
}
else if (actor is EffectActor)
{
return "EffectActor";
}
else if (actor is SoundActor)
{
return "SoundActor";
}
else if (actor is AINodeActor)
{
return "AINodeActor";
}
else if (actor is LightActor)
{
return "LightActor";
}
else if (actor is GroupActor)
{
if (actor is PrefebActor)
{
return "PrefebActor";
}
return "GroupActor";
}
else if (actor is DancerActor)
{
return "DancerActor";
}
AssertUtil.confirm(false);
return "";
}
// 得到多個物品的最小位置
public static Vector3F getMinPos(ActorBuffer ab)
{
if (ab.Count<IActor>() == 0)
{
return Vector3F.Zero;
}
IActor actor0 = ab.ElementAt<IActor>(0);
Vector3F pos = actor0.aabb.Min;
foreach (IActor actor in ab)
{
if (actor.aabb.Min.X < pos.X)
{
pos.X = actor.aabb.Min.X;
}
if (actor.aabb.Min.Y < pos.Y)
{
pos.Y = actor.aabb.Min.Y;
}
if (actor.aabb.Min.Z < pos.Z)
{
pos.Z = actor.aabb.Min.Z;
}
}
return pos;
}
得到多個物品的最小位置
//public static Vector3F getMinPos(ActorBuffer ab)
//{
// if (ab.Count<IActor>() == 0)
// {
// return Vector3F.Zero;
// }
// IActor actor0 = ab.ElementAt<IActor>(0);
// Vector3F pos = new Vector3F(actor0.locationmat.M14, actor0.locationmat.M24, actor0.locationmat.M34);
// foreach (IActor actor in ab)
// {
// if (actor.locationmat.M14 < pos.X)
// {
// pos.X = actor.locationmat.M14;
// }
// if (actor.locationmat.M24 < pos.Y)
// {
// pos.Y = actor.locationmat.M24;
// }
// if (actor.locationmat.M34 < pos.Z)
// {
// pos.Z = actor.locationmat.M34;
// }
// }
// return pos;
//}
// 得到多個物品的最大位置
public static Vector3F getMaxPos(ActorBuffer ab)
{
if (ab.Count<IActor>() == 0)
{
return Vector3F.Zero;
}
IActor actor0 = ab.ElementAt<IActor>(0);
Vector3F pos = actor0.aabb.Max;
foreach (IActor actor in ab)
{
if (actor.aabb.Max.X > pos.X)
{
pos.X = actor.aabb.Max.X;
}
if (actor.aabb.Max.Y > pos.Y)
{
pos.Y = actor.aabb.Max.Y;
}
if (actor.aabb.Max.Z > pos.Z)
{
pos.Z = actor.aabb.Max.Z;
}
}
return pos;
}
public static Vector3F ComputeCenter(ActorBuffer ab)
{
if (ab == null || ab.empty())
{
return new Vector3F();
}
if (ab.Count<IActor>() == 1)
{
return ab.ElementAt(0).center;
}
Vector3F max = getMaxPos(ab);
Vector3F min = getMinPos(ab);
Vector3F res = new Vector3F((max.X + min.X) / 2.0f, (max.Y + min.Y) / 2.0f, (max.Z + min.Z) / 2.0f);
return res;
}
public static void drawCircle(Vector3F center, Vector3F normal, float radius, Color color, ClientBridge.ClientRenderSys rendersys)
{
normal.Normalize();
// 用360個點的連線模拟圓
int pointcount = 360;
float[] points = new float[pointcount * 3];
int[] indexs = new int[pointcount * 3 + 1];
for (int t = 0; t < pointcount; t++)
{
float factor = 0;
Vector3F u = new Vector3F();
if (Math.Abs(normal.X) > Math.Abs(normal.Y))
{
factor = 1.0f / (float)Math.Sqrt(normal.X * normal.X + normal.Z * normal.Z);
u.X = -normal.Z * factor;
u.Y = 0;
u.Z = normal.X * factor;
}
else
{
factor = 1.0f / (float)Math.Sqrt(normal.Y * normal.Y + normal.Z * normal.Z);
u.X = 0;
u.Y = normal.Z * factor;
u.Z = -normal.Y * factor;
}
u.Normalize();
Vector3F v = Vector3F.CrossProduct(normal, u);
v.Normalize();
points[t * 3] = (float)(center.X + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.X + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.X);
points[t * 3 + 1] = (float)(center.Y + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Y + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Y);
points[t * 3 + 2] = (float)(center.Z + (radius * Math.Cos(Math.PI * t / 180.0f)) * u.Z + (radius * Math.Sin(Math.PI * t / 180.0f)) * v.Z);
indexs[t * 3] = t * 3;
indexs[t * 3 + 1] = t * 3 + 1;
indexs[t * 3 + 2] = t * 3 + 2;
}
indexs[pointcount * 3] = 0;
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_STRIP, points, indexs, color.toArray(), true);
}
public static void drawRotateCircles(List<uint> idlist, Vector3F center, ClientBridge.ClientRenderSys rendersys)
{
Color cr = new Color(1, 0, 0, 1);
Color cg = new Color(0, 1, 0, 1);
Color cb = new Color(0, 0, 1, 1);
if (idlist != null && idlist.Count >= 3)
{
rendersys.pushSelectID(idlist[0]);
}
GActorHelper.drawCircle(center, new Vector3F(1, 0, 0), 1, cr, rendersys); // 繪制垂直于x軸的圓
if (idlist != null && idlist.Count >= 3)
{
rendersys.pushSelectID(idlist[1]);
}
GActorHelper.drawCircle(center, new Vector3F(0, 1, 0), 1, cg, rendersys); // 繪制垂直于y軸的圓
if (idlist != null && idlist.Count >= 3)
{
rendersys.pushSelectID(idlist[2]);
}
GActorHelper.drawCircle(center, new Vector3F(0, 0, 1), 1, cb, rendersys); // 繪制垂直于z軸的圓
//List<float> viewmat = new List<float>();
//for (int i = 0; i < 16; i++)
//{
// viewmat.Add(0);
//}
//rendersys.getPerspective(viewmat);
//Vector3F dir = new Vector3F(viewmat[0], viewmat[4], viewmat[8]);
//GActorHelper.drawCircle(center, dir, 2, cr, rendersys);
float[] points = { center.X, center.Y, center.Z, // 0 o
center.X + 1, center.Y, center.Z, // 1 x
center.X, center.Y + 1, center.Z, // 2 y
center.X, center.Y,center.Z + 1, // 3 z
};
int[] indexsx = { 0, 1 };
int[] indexsy = { 0, 2 };
int[] indexsz = { 0, 3 };
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexsx, cr.toArray(), true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexsy, cg.toArray(), true);
rendersys.drawIndex(ClientBridge.IndexDrawType.LDT_LINE_LIST, points, indexsz, cb.toArray(), true);
}
}
// 物品管理層借口類,可以有子層
// fixme: 子層沒有記錄在scenegraph裡面
public interface IActorLayerMng : IEditItem
{
// 獲得原始物品容器
ActorBuffer getOrgBuffer();
// 獲得選中物品容器
ActorBuffer getSelBuffer();
// 獲得屬性清單
IDictionary<String, String> getPropertyList();
// 物品包圍盒變化
void OnActorAABBChanged(IActor actor, AxisAlignedBox aabb);
// 修改key對應的value
void notifyPropertyChange(String key, String value);
// 獲得目前的物品管理層
IActorLayerMng currentLayerMng { get; set; }
// 設定最具體的目前的編輯層,如果layer不在目前層會繼續到下一層設定
void setCurrentLayerMng(IActorLayerMng layer);
// 獲得目前的編輯層,與currentLayerMng不同的是:這個函數可以獲得最具體的目前編輯層
IActorLayerMng getCurrentLayerMng();
// 獲得根物品管理器
IActorLayerMng getRootActorLayer();
// 看給定的layer,在那個子物品管理器中
IActorLayerMng getSubRootActorLayer(IActorLayerMng layer);
// 獲得所有的子物品管理層
IList<IActorLayerMng> getList();
// 清空所有内容
void clean();
// 獲得父親類
IActorLayerMng parent
{
get;
set;
}
string name
{
get;
set;
}
// 獲得目前layer的位置偏移量
// fixme: 幫助函數,接口類中不應該定義
void getOffset(ref float delx, ref float dely);
//建立子層
IActorLayerMng createSubActorLayer();
// 更新
void update(int t);
void UpdateCpuSkin(float t);
// 繪制
void render(int t, ClientBridge.ClientRenderSys rendersys);
// 繪制包圍盒
void renderAABB(int t, ClientBridge.ClientRenderSys rendersys);
// 繪制移動控制軸
void renderCoordinate(int t, ClientBridge.ClientRenderSys rendersys);
// 繪制移動控制軸
void renderSingleCircle(int t, ClientBridge.ClientRenderSys rendersys);
// 繪制旋轉控制圈
void renderCircles(int t, ClientBridge.ClientRenderSys rendersys);
// 儲存層中的物品
bool serialize(BinaryWriter binWriter);
// 讀取物品
bool serialize(BinaryReader binReader, IEditItem edititem);
// save
bool serialize(System.Xml.XmlNode xmlnode, IEditItem edititem, bool clipboard);
// load
bool serialize(System.Xml.XmlNode xmlnode, IEditItem edititem, IMacroCommand cmd, bool clipboard);
void customHardwareSelect(Dictionary<IActorLayerMng, ActorBuffer> selactors, IView view, Rect<int> rect, bool selectfirst);
// 将物品添加到硬體選擇
void pushHardwareSelect(ClientBridge.ClientRenderSys rendersys);
void pushLineHardwareSelect(ClientBridge.ClientRenderSys rendersys);
// 将物品移動控制軸添加到硬體選擇
void pushHardwareSelect_Move(ClientBridge.ClientRenderSys rendersys);
// 将物品旋轉控制圓添加到硬體選擇
void pushHardwareSelect_Rotate(RotateMode rm, ClientBridge.ClientRenderSys rendersys);
// 将指定ID對應的物品添加到dictionary中
void getSelectByID(Dictionary<IActorLayerMng, ActorBuffer> selactors, int id);
// 傳回指定ID對應的移動控制軸的編号
int getSelectMoveLineID(int id);
// 傳回指定ID對應的旋轉控制圓的編号
int getSelectRotateCircleID(int id);
// 是否可以複制、剪切
bool canCopyCut();
// 是否可以粘貼
bool canPaste();
//判斷是否可執行group操作
bool canCreateGroup();
bool canDestroyGroup();
bool canOpenGroup();
bool canCloseGroup();
bool canDettachGroup();
bool canAttachGroup();
//建立物品組 不同的物品層可能會建立不同類型的GruopActor
GroupActor createLayerActorGroup(string name, out ActorBuffer ab);
//設定所有actor的lod級别
void setActorMaterialLod(ClientBridge.LOD_LEVEL lod);
//父層的Hide狀态改變,回調通知子層及子Actor
void notifyLayerHide(bool isHide);
//父層的Freeze狀态改變,回調通知子層及子Actor
void notifyLayerFreeze(bool isFreeze);
//傳回用于層管理器中的層清單
IList<IActorLayerMng> getLayersToManage();
}
// 物品管理層實作類
public class ActorLayerMngImp : BaseEditItem, IActorLayerMng
{
// fixme: 應該通過子容器的屬性設定,而不是用這個值來表示
IActorLayerMng m_cur_actor_layer = null;
List<IActorLayerMng> m_actor_layer_list = new List<IActorLayerMng>();
String m_name;
ActorBuffer m_org_buffer;
ActorBuffer m_sel_buffer;
// 屬性清單,用來記錄若幹物品資訊
IDictionary<String, String> m_property_list = new Dictionary<String, String>();
IActorLayerMng m_parent = null;
// 獲得父親類
public IActorLayerMng parent
{
get { return m_parent; }
set { m_parent = value; }
}
public string name
{
get { return m_name; }
set { m_name = value; }
}
// orgfun表示将物品從原始物品清單中移入移出需要調用的函數
// selfun表示将物品從選擇物品清單中移入移出需要調用的函數
public ActorLayerMngImp(IEditItem parent, IActorFun orgfun, IActorFun selfun)
{
m_org_buffer = new ActorBuffer(this, orgfun);
m_sel_buffer = new ActorBuffer(this, selfun);
m_parent = (IActorLayerMng)parent;
name = "物品簇";
}
public ActorLayerMngImp(IEditItem parent, IActorFun orgfun, IActorFun selfun, string name_string)
{
m_org_buffer = new ActorBuffer(this, orgfun);
m_sel_buffer = new ActorBuffer(this, selfun);
m_parent = (IActorLayerMng)parent;
name = name_string;
}
/// <summary>
/// 用于序列化
/// </summary>
public ActorLayerMngImp()
{
}
// 儲存
public bool serialize(BinaryWriter binWriter)
{
// 儲存ActorLayer自身資訊
binWriter.Write(name); // string
binWriter.Write(getOrgBuffer().Count<IActor>()); // 物品個數
binWriter.Write(getList().Count<IActorLayerMng>()); // 子層個數
// 儲存各子物品
foreach (IActor actor in getOrgBuffer())
{
binWriter.Write(GActorHelper.getActorTypestr(actor));
actor.serialize(binWriter);
}
// 儲存各子層
foreach (IActorLayerMng sublayer in getList())
{
sublayer.serialize(binWriter);
}
return true;
}
// 讀取
public bool serialize(BinaryReader binReader, IEditItem edititem)
{
name = binReader.ReadString();
int actornum = binReader.ReadInt32();
int sublayernum = binReader.ReadInt32();
for (int i = 0; i < actornum; i++)
{
string type = binReader.ReadString();
IActor actor = null;
if (type == "PrefebActor")
{
string groupname = binReader.ReadString();
string prefebname = binReader.ReadString();
actor = PrefebManager.getActorBufferFromPrefebFile(groupname, prefebname, edititem);
}
else
{
actor = GActorHelper.generateActorWithoutInfo(type, edititem);
}
if (actor != null)
{
actor.serialize(binReader, edititem);
getOrgBuffer().insert(actor);
}
}
for (int i = 0; i < sublayernum; i++)
{
IActorLayerMng sublayer = new ActorLayerMngImp(this, new DummyActorFun(), new DummyActorFun());
BaseCommand.getDocLogic(edititem).addCommand(new AddActorLayerCmd(this, sublayer));
sublayer.serialize(binReader, edititem);
}
return true;
}
// save
public virtual bool serialize(System.Xml.XmlNode xmlnode, IEditItem edititem, bool clipboard)
{
System.Xml.XmlNode subnode;
XmlAttribute att;
// 儲存ActorLayer自身資訊
att = xmlnode.OwnerDocument.CreateAttribute("Name");
att.Value = name;
xmlnode.Attributes.Append(att);
att = xmlnode.OwnerDocument.CreateAttribute("Hide");
att.Value = BaseCommand.isValueTrue(getPropertyList(), "hide").ToString();
xmlnode.Attributes.Append(att);
att = xmlnode.OwnerDocument.CreateAttribute("Freeze");
att.Value = BaseCommand.isValueTrue(getPropertyList(), "freeze").ToString();
xmlnode.Attributes.Append(att);
// 儲存各子物品
foreach (IActor actor in (clipboard ? getSelBuffer() : getOrgBuffer()))
{
if ((actor.flag & (int)ActorFlag.UNSERIALIZABLE) == 0)
{
subnode = xmlnode.OwnerDocument.CreateNode("element", "Actor", "");
att = xmlnode.OwnerDocument.CreateAttribute("Type");
att.Value = GActorHelper.getActorTypestr(actor);
subnode.Attributes.Append(att);
actor.serialize(subnode, edititem, false, clipboard);
xmlnode.InsertAfter(subnode, xmlnode.LastChild);
}
}
// 儲存各子層
foreach (IActorLayerMng sublayer in getList())
{
subnode = xmlnode.OwnerDocument.CreateNode("element", "Layer", "");
sublayer.serialize(subnode, edititem, clipboard);
xmlnode.InsertAfter(subnode, xmlnode.LastChild);
}
return true;
}
// load
public virtual bool serialize(System.Xml.XmlNode xmlnode, IEditItem edititem, IMacroCommand cmd, bool clipboard)
{
//ClientBridge.Profile.Begin(129);
ActorBuffer actor_buffer = new ActorBuffer(null, new DummyActorFun());
foreach (System.Xml.XmlNode subnode in xmlnode.SelectNodes("Actor"))
{
XmlElement ele = (XmlElement)subnode;
string type = ele.GetAttribute("Type");
IActor actor = null;
if (type == "PrefebActor")
{
string groupname = ele.GetAttribute("GroupName");
string prefebname = ele.GetAttribute("PrefebName");
actor = PrefebManager.getActorBufferFromPrefebFile(groupname, prefebname, edititem);
foreach (XmlNode childnode in subnode.ChildNodes)
{
if (childnode.Name != "Item" && childnode.Name != "LocationMat")
{
actor.notifyPropertyChange(childnode.Name, childnode.InnerText);
}
}
XmlNode node = subnode.SelectSingleNode("LocationMat");
if (node != null)
{
Matrix4F locationmat = Matrix4F.setMatrix(node.InnerText);
PrefebManager.allrotateandmove((PrefebActor)actor, new Matrix4F(locationmat));
}
actor_buffer.insert(actor);
}
else
{
actor = GActorHelper.generateActorWithoutInfo(type, edititem);
if (actor != null)
{
actor.serialize(subnode, edititem, true, clipboard);
actor_buffer.insert(actor);
}
}
}
if (clipboard)
{
cmd.addCmd(new InsertCmd(this, actor_buffer));
}
else
{
getOrgBuffer().add(actor_buffer);
}
foreach (System.Xml.XmlNode subnode in xmlnode.SelectNodes("Layer"))
{
string layer_name = ((XmlElement)subnode).GetAttribute("Name");
IActorLayerMng sublayer = GetLayerByName(layer_name);
if (sublayer == null)
{
sublayer = this.createSubActorLayer();
sublayer.name = layer_name;
this.getList().Add(sublayer);
}
sublayer.serialize(subnode, edititem, cmd, clipboard);
if (((XmlElement)subnode).HasAttribute("Hide") && ((XmlElement)subnode).HasAttribute("Freeze"))
{
sublayer.notifyPropertyChange("hide", ((XmlElement)subnode).GetAttribute("Hide").ToLower());
sublayer.notifyPropertyChange("freeze", ((XmlElement)subnode).GetAttribute("Freeze").ToLower());
}
SceneGraph.notify((IEditItem)SceneGraph.getEditItemCommon("RootItem", this.getRootActorLayer()), NotifyType.ACTOR, "LayerInsert/Remove", "");
}
//ClientBridge.Profile.End(129);
return true;
}
protected IActorLayerMng GetLayerByName(string layer_name)
{
foreach (IActorLayerMng layer in m_actor_layer_list)
{
if (layer_name == layer.name)
{
return layer;
}
}
return null;
}
public virtual void setActorMaterialLod(ClientBridge.LOD_LEVEL lod)
{
IEnumerator<IActor> it_actor = Tool.GetActorsFromLayerManager<IActor>(this, true, true, true).GetEnumerator();
while (it_actor.MoveNext())
{
if (it_actor.Current is ResActorBase)
{
((ResActorBase)it_actor.Current).SetLod(lod);
}
}
}
// 原始物品清單
public ActorBuffer getOrgBuffer()
{
return m_org_buffer;
}
// 選中物品清單
public ActorBuffer getSelBuffer()
{
return m_sel_buffer;
}
public IDictionary<string, string> getPropertyList()
{
return m_property_list;
}
public virtual void OnActorAABBChanged(IActor actor, AxisAlignedBox aabb)
{
}
public void notifyPropertyChange(string key, string value)
{
m_property_list[key] = value;
}
//建立子層預設操作
public virtual IActorLayerMng createSubActorLayer()
{
return new ActorLayerMngImp(this, new DummyActorFun(), new DummyActorFun());
}
// 需要根據類型進行設定和擷取
public IActorLayerMng currentLayerMng
{
get
{
return m_cur_actor_layer;
}
set
{
m_cur_actor_layer = value;
}
}
public void setCurrentLayerMng(IActorLayerMng layer)
{
if (layer == this)
{
currentLayerMng = null;
return;
}
else
{
IActorLayerMng sublayer = getSubRootActorLayer(layer);
AssertUtil.confirm(sublayer != null);
currentLayerMng = sublayer;
sublayer.setCurrentLayerMng(layer);
}
}
public IActorLayerMng getCurrentLayerMng()
{
if (currentLayerMng == null)
return this;
else
return currentLayerMng.getCurrentLayerMng();
}
public IActorLayerMng getRootActorLayer()
{
if (parent != null)
return parent.getRootActorLayer();
else
return this;
}
public IActorLayerMng getSubRootActorLayer(IActorLayerMng layer)
{
foreach (IActorLayerMng subactorlayer in m_actor_layer_list)
{
if (subactorlayer == layer)
return subactorlayer;
else if (subactorlayer.getSubRootActorLayer(layer) != null)
return subactorlayer;
}
return null;
}
public void getOffset(ref float delx, ref float dely)
{
if (currentLayerMng == null)
{
return;
}
else
{
// 找到current layer所對應的物品,然後累計偏移量
foreach (IActor actor in getOrgBuffer())
{
if (actor.getActorBuffer() == currentLayerMng)
{
delx += actor.rect.x;
dely += actor.rect.y;
currentLayerMng.getOffset(ref delx, ref dely);
return;
}
}
}
}
public IList<IActorLayerMng> getList()
{
return m_actor_layer_list;
}
override public void Dispose()
{
clean();
base.Dispose();
}
public virtual void clean()
{
foreach (IActor actor in m_org_buffer)
{
actor.Dispose();
}
m_org_buffer.clear();
m_sel_buffer.clear();
foreach (IActorLayerMng al in m_actor_layer_list)
{
al.Dispose();
}
m_actor_layer_list.Clear();
m_cur_actor_layer = null;
}
public static IActorLayerMng getCurrentLayerMng(IActorLayerMng layermng)
{
while (true)
{
if (layermng.currentLayerMng != null)
layermng = layermng.currentLayerMng; // go deeper
else
return layermng;
}
}
public virtual void customHardwareSelect(Dictionary<IActorLayerMng, ActorBuffer> selactors, IView view, Rect<int> rect, bool selectfirst)
{
}
public void pushHardwareSelect(ClientBridge.ClientRenderSys rendersys)
{
foreach (IActor actor in m_org_buffer)
{
actor.pushHardwareSelect(rendersys);
}
foreach (IActorLayerMng sublayer in getList())
{
sublayer.pushHardwareSelect(rendersys);
}
}
public virtual void pushLineHardwareSelect(ClientBridge.ClientRenderSys rendersys)
{
foreach (IActor actor in m_org_buffer)
{
if (!actor.hide && !actor.freeze)
{
actor.pushLineHardwareSelect(rendersys);
}
}
foreach (IActorLayerMng sublayer in getList())
{
sublayer.pushLineHardwareSelect(rendersys);
}
}
public void pushHardwareSelect_Move(ClientBridge.ClientRenderSys rendersys)
{
foreach (IActor actor in m_org_buffer)
{
actor.pushHardwareSelect_Move(rendersys);
}
foreach (IActorLayerMng sublayer in getList())
{
sublayer.pushHardwareSelect_Move(rendersys);
}
}
public void pushHardwareSelect_Rotate(RotateMode rm, ClientBridge.ClientRenderSys rendersys)
{
switch (rm)
{
case RotateMode.RM_SELF:
foreach (IActor actor in m_org_buffer)
{
actor.pushHardwareSelect_Rotate(rendersys);
}
foreach (IActorLayerMng sublayer in getList())
{
sublayer.pushHardwareSelect_Rotate(rm, rendersys);
}
break;
case RotateMode.RM_WHOLE:
List<uint> idlist = new List<uint>();
idlist.Add(0);
idlist.Add(1);
idlist.Add(2);
ActorBuffer ab = new ActorBuffer(null, new DummyActorFun());
GActorHelper.getActors(ab, this, true, false);
Vector3F max = GActorHelper.getMaxPos(ab);
Vector3F min = GActorHelper.getMinPos(ab);
Vector3F center = new Vector3F((max.X + min.X) / 2.0f, (max.Y + min.Y) / 2.0f, (max.Z + min.Z) / 2.0f);
GActorHelper.drawRotateCircles(idlist, center, rendersys);
break;
default:
break;
}
}
public int getSelectMoveLineID(int id)
{
foreach (IActor actor in m_org_buffer)
{
for (int i = 0; i < actor.giid_move.Count; i++)
{
if (actor.giid_move[i].value == id)
{
return i;
}
}
//對Group的處理
if (actor is GroupActor)
{
GroupActor ga = actor as GroupActor;
int reid = ga.getActorBuffer().getSelectMoveLineID(id);
if (reid != -1)
{
return reid;
}
}
}
foreach (IActorLayerMng sublayer in getList())
{
int reid = sublayer.getSelectMoveLineID(id);
if (reid != -1)
{
return reid;
}
}
return -1;
}
public int getSelectRotateCircleID(int id)
{
foreach (IActor actor in m_org_buffer)
{
for (int i = 0; i < actor.giid_rotate.Count; i++)
{
if (actor.giid_rotate[i].value == id)
{
return i;
}
}
// 對Group的處理
if (actor is GroupActor)
{
GroupActor ga = actor as GroupActor;
int reid = ga.getActorBuffer().getSelectRotateCircleID(id);
if (reid != -1)
{
return reid;
}
}
}
foreach (IActorLayerMng sublayer in getList())
{
int reid = sublayer.getSelectRotateCircleID(id);
if (reid != -1)
{
return reid;
}
}
return -1;
}
public void getSelectByID(Dictionary<IActorLayerMng, ActorBuffer> selactors, int id)
{
foreach (IActor actor in m_org_buffer)
{
if (actor.giid.value == id)
{
if (!selactors.ContainsKey(this))
{
selactors[this] = new ActorBuffer(null, new DummyActorFun());
}
if (!selactors[this].Contains<IActor>(actor))
{
selactors[this].insert(actor);
}
return;
}
// 對Group的特殊處理
if (actor is GroupActor)
{
((GroupActor)actor).getSelectByID(selactors, id, this);
}
}
foreach (IActorLayerMng sublayer in getList())
{
sublayer.getSelectByID(selactors, id);
}
}
public virtual void update(int t)
{
//ClientBridge.Profile.Begin(89);
ActorBuffer ab = getOrgBuffer();
foreach (IActor actor in ab)
{
actor.update(t);
}
IList<IActorLayerMng> sublist = getList();
foreach (IActorLayerMng alm in sublist)
{
alm.update(t);
}
// ClientBridge.Profile.End(89);
}
public virtual void UpdateCpuSkin(float t)
{
ActorBuffer ab = getOrgBuffer();
foreach (IActor actor in ab)
{
actor.UpdateCpuSkin(t);
}
IList<IActorLayerMng> sublist = getList();
foreach (IActorLayerMng alm in sublist)
{
alm.UpdateCpuSkin(t);
}
}
virtual public void render(int t, ClientBridge.ClientRenderSys rendersys)
{
// 繪制目前層所有物品
ActorBuffer ab = getOrgBuffer();
foreach (IActor actor in ab)
{
if (!actor.hide)
{
actor.render(t, rendersys);
}
}
// 繪制子層
IList<IActorLayerMng> sublist = getList();
foreach (IActorLayerMng alm in sublist)
{
alm.render(t, rendersys);
}
}
public void renderAABB(int t, ClientBridge.ClientRenderSys rendersys)
{
// 繪制選中物品包圍盒
ActorBuffer sab = getSelBuffer();
foreach (IActor sactor in sab)
{
if (!sactor.hide)
{
Color color = (sactor is PrefebActor) ? (new Color(1, 1, 0, 1)) : (new Color(1, 1, 1, 1));
sactor.renderAABB(t, rendersys, color);
if (sactor.parent is GroupActor)
{
sactor.parent.renderAABB(t, rendersys, new Color(0, 1, 1, 1));
}
}
}
//某些chr即使沒有 被選中也需要繪制aabb
ActorBuffer orgbuffer = getOrgBuffer();
foreach (IActor actor in orgbuffer)
{
if (!actor.hide && actor.GetActorType()==ACTOR_TYPE.AT_CHR)
{
Color color = (actor is PrefebActor) ? (new Color(1, 1, 0, 1)) : (new Color(1, 1, 1, 1));
// actor.renderAABB(t, rendersys, color);
}
}
// 繪制子層
IList<IActorLayerMng> sublist = getList();
foreach (IActorLayerMng alm in sublist)
{
alm.renderAABB(t, rendersys);
}
}
public void renderCoordinate(int t, ClientBridge.ClientRenderSys rendersys)
{
// 繪制選中物品Coordinate
ActorBuffer sab = getSelBuffer();
foreach (IActor sactor in sab)
{
if (!sactor.hide)
{
sactor.renderCoordinate(t, rendersys);
}
}
// 繪制子層
IList<IActorLayerMng> sublist = getList();
foreach (IActorLayerMng alm in sublist)
{
alm.renderCoordinate(t, rendersys);
}
}
public void renderCircles(int t, ClientBridge.ClientRenderSys rendersys)
{
// 繪制選中物品Coordinate
ActorBuffer sab = getSelBuffer();
foreach (IActor sactor in sab)
{
if (!sactor.hide)
{
sactor.renderCircles(t, rendersys);
}
}
// 繪制子層
IList<IActorLayerMng> sublist = getList();
foreach (IActorLayerMng alm in sublist)
{
alm.renderCircles(t, rendersys);
}
}
public void renderSingleCircle(int t, ClientBridge.ClientRenderSys rendersys)
{
ActorBuffer ab = new ActorBuffer(null, new DummyActorFun());
GActorHelper.getActors(ab, this, true, false);
if (ab.Count<IActor>() == 0)
{
return;
}
Vector3F max = GActorHelper.getMaxPos(ab);
Vector3F min = GActorHelper.getMinPos(ab);
Vector3F center = new Vector3F((max.X + min.X) / 2.0f, (max.Y + min.Y) / 2.0f, (max.Z + min.Z) / 2.0f);
GActorHelper.drawRotateCircles(null, center, rendersys);
}
// 是否可以複制、剪切
public virtual bool canCopyCut()
{
return !getSelBuffer().empty();
}
// 是否可以粘貼
public virtual bool canPaste()
{
return Clipboard.ContainsData(DataFormats.Text) && !BaseCommand.isActorLayerReadOnly(this);
}
public virtual bool canCreateGroup()
{
int actorCount = 0;
ActorBuffer sel_ab = new ActorBuffer(null, new DummyActorFun());
GActorHelper.getActors(sel_ab, getRootActorLayer(), true, false, true);
foreach (IActor actor in sel_ab)
{
if (actor.parent == null)
actorCount++;
}
return actorCount > 0;
}
private void getSelectedGroupActors(IActorLayerMng layer, List<ActorBuffer> buffers)
{
ActorBuffer b1 = layer.getSelBuffer().getTypeActors(typeof(GroupActor));
if (!b1.empty())
buffers.Add(b1);
foreach (IActorLayerMng sub_layer in layer.getList())
{
getSelectedGroupActors(sub_layer, buffers);
}
}
private List<ActorBuffer> getSelectedGroupActors(IActorLayerMng layer)
{
List<ActorBuffer> buffers = new List<ActorBuffer>();
getSelectedGroupActors(layer, buffers);
return buffers;
}
public virtual bool canDestroyGroup()
{
List<ActorBuffer> buffers = getSelectedGroupActors(getRootActorLayer());
return buffers.Count > 0;
}
public virtual bool canOpenGroup()
{
List<ActorBuffer> buffers = getSelectedGroupActors(getRootActorLayer());
int actorCount = 0;
foreach (ActorBuffer ab in buffers)
{
foreach (GroupActor ga in ab)
{
if (ga.close)
actorCount++;
}
}
return actorCount > 0;
}
public virtual bool canCloseGroup()
{
List<ActorBuffer> buffers = getSelectedGroupActors(getRootActorLayer());
int actorCount = 0;
foreach (ActorBuffer ab in buffers)
{
foreach (GroupActor ga in ab)
{
if (!ga.close)
actorCount++;
}
}
return actorCount > 0;
}
public virtual bool canDettachGroup()
{
int actorCount = 0;
ActorBuffer sel_ab = new ActorBuffer(null, new DummyActorFun());
GActorHelper.getActors(sel_ab, getRootActorLayer(), true, false, true);
foreach (IActor actor in sel_ab)
{
GroupActor ga = actor.parent as GroupActor;
if (ga != null)
{
actorCount++;
}
}
return actorCount > 0;
}
public virtual bool canAttachGroup()
{
return true;
}
public virtual GroupActor createLayerActorGroup(string name, out ActorBuffer outAb)
{
ActorBuffer sel_ab = new ActorBuffer(null, new DummyActorFun());
GActorHelper.getActors(sel_ab, getRootActorLayer(), true, false, true);
RootEditItem root = (RootEditItem)(SceneGraph.getEditItemCommon("RootItem", getRootActorLayer()));
ActorBuffer ab = new ActorBuffer(null, new DummyActorFun());
foreach (IActor actor in sel_ab)
{
if (actor.parent == null)
ab.insert(actor);
}
if (ab.empty())
{
outAb = null;
return null;
}
outAb = ab;
int group_index = 0;
if (name == null || name.Length == 0)
{
IDocFactory df = (IDocFactory)SceneGraph.getEditItemCommon("DocFactory", root);
IDoc doc = (IDoc)SceneGraph.getEditItemCommon("doc", df);
group_index = doc.getMaxActorIndex("Group");
}
Dictionary<string, string> createpropdic = new Dictionary<string, string>();
createpropdic["NamePrefix"] = "Group";
createpropdic["Height"] = "0";
GroupActor ga = new GroupActor(root.giidmng, createpropdic, group_index, this);
if (name != null && name.Length > 0)
ga.name = name;
return ga;
}
//傳回用于層管理器中的層清單
public virtual IList<IActorLayerMng> getLayersToManage()
{
return getList();
}
//父層的Hide狀态改變,回調通知子層及子Actor
virtual public void notifyLayerHide(bool isHide)
{
if (BaseCommand.isValueTrue(getPropertyList(), "hide"))
return;
foreach (IActorLayerMng layer in m_actor_layer_list)
layer.notifyLayerHide(isHide);
foreach (IActor actor in m_org_buffer)
actor.notifyLayerHide(isHide);
}
//父層的Freeze狀态改變,回調通知子層及子Actor
virtual public void notifyLayerFreeze(bool isFreeze)
{
if (BaseCommand.isValueTrue(getPropertyList(), "freeze"))
return;
foreach (IActorLayerMng layer in m_actor_layer_list)
layer.notifyLayerFreeze(isFreeze);
foreach (IActor actor in m_org_buffer)
actor.notifyLayerFreeze(isFreeze);
}
}
public interface IResHandle
{
string ResName { get; }
object getRes();
void reload();
void changeRes(ClientBridge.ClientRenderSys rendersys, string new_res);
void addRef();
int ResRefCount { get; }
List<IResHandle> getSubResHandleList();
}
public class ResActorBase : ActorBase, IResHandle
{
public ResActorBase(GIIDMng giidmng)
: base(giidmng)
{
}
virtual public string ResName
{
get { return ""; }
}
virtual public object getRes()
{
return null;
}
virtual public void reload()
{
}
virtual public void changeRes(ClientBridge.ClientRenderSys rendersys, string new_res)
{
}
new virtual public void Attach(ClientBridge.SceneBase scene)
{
}
new virtual public void Detach(ClientBridge.SceneBase scene)
{
}
virtual public void addRef()
{
}
virtual public int ResRefCount
{
get { return 1; }
}
virtual public List<IResHandle> getSubResHandleList()
{
return new List<IResHandle>();
}
new protected bool CanTransform()
{
return ResRefCount == 1;
}
}
[Serializable]
public class MultiActorFun : IActorFun
{
public void AddFun(IActorFun actorfun)
{
if (m_actorfun_list.GetIndex(actorfun) == -1)
{
m_actorfun_list.Add(actorfun);
}
}
public void insert(IActor actor, IActorLayerMng layer)
{
foreach (IActorFun actorfun in m_actorfun_list)
{
actorfun.insert(actor, layer);
}
}
public void remove(IActor actor, IActorLayerMng layer)
{
foreach (IActorFun actorfun in m_actorfun_list)
{
actorfun.remove(actor, layer);
}
}
ListEx<IActorFun> m_actorfun_list = new ListEx<IActorFun>();
}
public class SceneActorFun : IActorFun
{
public SceneActorFun(ClientBridge.SceneBase scene)
{
m_scene = scene;
}
public void SetScene(ClientBridge.SceneBase scene)
{
m_scene = scene;
}
public void insert(IActor actor, IActorLayerMng layer)
{
if (m_scene != null && actor is ResActorBase)
{
((ResActorBase)actor).Attach(m_scene);
}
}
public void remove(IActor actor, IActorLayerMng layer)
{
if (m_scene != null && actor is ResActorBase)
{
((ResActorBase)actor).Detach(m_scene);
}
}
ClientBridge.SceneBase m_scene;
}
}