SceneGraph.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868
  1. /*
  2. * Copyright (c) OpenSim project, http://sim.opensecondlife.org/
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. * * Redistributions of source code must retain the above copyright
  7. * notice, this list of conditions and the following disclaimer.
  8. * * Redistributions in binary form must reproduce the above copyright
  9. * notice, this list of conditions and the following disclaimer in the
  10. * documentation and/or other materials provided with the distribution.
  11. * * Neither the name of the <organization> nor the
  12. * names of its contributors may be used to endorse or promote products
  13. * derived from this software without specific prior written permission.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
  16. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
  19. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  22. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. *
  26. */
  27. using System;
  28. using System.IO;
  29. using System.Collections.Generic;
  30. using System.Threading;
  31. using libsecondlife;
  32. using libsecondlife.Packets;
  33. using Axiom.MathLib;
  34. namespace OpenSim
  35. {
  36. /// <summary>
  37. /// Manages prim and avatar sim positions and movements and updating clients
  38. /// </summary>
  39. public class SceneGraph
  40. {
  41. public Node RootNode;
  42. public Terrain Terrain;
  43. private Thread _mthread;
  44. private PhysicsManager _physics;
  45. private Server _server;
  46. private System.Text.Encoding _enc = System.Text.Encoding.ASCII;
  47. private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock _avatarTemplate;
  48. private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock PrimTemplate;
  49. private int _objectCount=0;
  50. private UpdateSender _updateSender;
  51. private AgentManager _agentManager;
  52. public NonBlockingQueue<UpdateCommand> Commands;
  53. #region Thread Sync
  54. //public object CommandsSync = new object();
  55. private object _sendTerrainSync = new object();
  56. #endregion
  57. public SceneGraph(Server server, AgentManager agentManager)
  58. {
  59. _server = server;
  60. RootNode = new Node();
  61. _physics = new PhysicsManager(this);
  62. Commands = new NonBlockingQueue<UpdateCommand>();
  63. Terrain = new Terrain();
  64. _updateSender = new UpdateSender(_server, agentManager);
  65. _agentManager = agentManager;
  66. //testing
  67. this.SetupAvatarTemplate("objectupate168.dat");
  68. this.SetupObjectTemplate("objectupate164.dat");
  69. _updateSender.Startup();
  70. }
  71. public void Startup()
  72. {
  73. _mthread = new Thread(new System.Threading.ThreadStart(RunScene));
  74. _mthread.IsBackground = true;
  75. _mthread.Start();
  76. }
  77. public void RunScene()
  78. {
  79. try
  80. {
  81. for(;;)
  82. {
  83. //Should be run at a fixed frame rate
  84. this.Update();
  85. }
  86. }
  87. catch (Exception e)
  88. {
  89. Console.WriteLine(e.Message);
  90. }
  91. }
  92. //will be called from the RunScene thread but for now is called by the timer thread.
  93. public void Update()
  94. {
  95. // run physics engine to update positions etc since last frame
  96. this._physics.UpdatePhysics();
  97. // process command list
  98. lock(this.Commands) //do we want to stop new commands being added while we process?
  99. {
  100. while(this.Commands.Count > 0)
  101. {
  102. UpdateCommand command = this.Commands.Dequeue();
  103. switch(command.CommandType)
  104. {
  105. case 1:
  106. //movement command
  107. if(command.SObject.SceneType == 1)
  108. {
  109. AvatarData avatar =(AvatarData) command.SObject;
  110. avatar.Walk = !avatar.Walk;
  111. command.SObject.InternVelocityX = command.InternVelocityX;
  112. command.SObject.InternVelocityY = command.InternVelocityY;
  113. command.SObject.InternVelocityZ = command.InternVelocityZ;
  114. command.SObject.Velocity = command.Velocity;
  115. if((command.SObject.UpdateFlag & (1)) != 1)
  116. {
  117. command.SObject.UpdateFlag += 1;
  118. }
  119. }
  120. break;
  121. default:
  122. break;
  123. }
  124. }
  125. }
  126. // check to see if any new avatars have joined since last frame
  127. //if so send data to clients.
  128. lock(this.RootNode)
  129. {
  130. for (int i = 0; i < this.RootNode.ChildrenCount; i++)
  131. {
  132. //for now we will limit avatars to being a child of the rootnode
  133. if(this.RootNode.GetChild(i).SceneType == 1) //check it is a avatar node
  134. {
  135. AvatarData avatar =(AvatarData) this.RootNode.GetChild(i);
  136. int updatemask = avatar.UpdateFlag & (128);
  137. if(updatemask == 128) //is a new avatar?
  138. {
  139. //Console.WriteLine("new avatar has been added to scene so update it on the current scene");
  140. this.SendAvatarDataToAll(avatar);
  141. //should send a avatar appearance to other clients except the avatar's owner
  142. this.SendAvatarAppearanceToAllExcept(avatar);
  143. //and send complete scene update to the new avatar's owner
  144. this.SendCompleteSceneTo(avatar);
  145. avatar.Started = true;
  146. }
  147. }
  148. }
  149. }
  150. //check for new prims
  151. lock(this.RootNode)
  152. {
  153. for (int i = 0; i < this.RootNode.ChildrenCount; i++)
  154. {
  155. if(this.RootNode.GetChild(i).SceneType == 2) //check it is a prim node
  156. {
  157. PrimData prim =(PrimData) this.RootNode.GetChild(i);
  158. if((prim.UpdateFlag & (64)) == 64)
  159. {
  160. //send prim data to all clients
  161. this.SendPrimToAll(prim);
  162. }
  163. }
  164. }
  165. }
  166. //send updates to clients
  167. //might be better to do these updates reverse to how is done here
  168. // ie.. loop through the avatars and find objects /other avatars in their range/vision
  169. //instead of looping through all objects/avatars and then finding avatars in range
  170. //but that would mean looping through all objects/avatar for each avatar,
  171. //rather than looping through just the avatars for each object/avatar
  172. lock(this.RootNode)
  173. {
  174. for (int i = 0; i < this.RootNode.ChildrenCount; i++)
  175. {
  176. if(this.RootNode.GetChild(i).SceneType == 1) //check it is a avatar node
  177. {
  178. AvatarData avatar =(AvatarData) this.RootNode.GetChild(i);
  179. int updatemask = avatar.UpdateFlag & (1);
  180. if(updatemask == 1)
  181. {
  182. //avatar has changed velocity
  183. //check what avatars are in range and add to their update lists
  184. //but for now we will say all avatars are in range
  185. for (int n = 0; n < this.RootNode.ChildrenCount; n++)
  186. {
  187. if(this.RootNode.GetChild(n).SceneType == 1) //check it is a avatar node
  188. {
  189. AvatarData avatar2 =(AvatarData) this.RootNode.GetChild(i);
  190. int newmask = avatar2.UpdateFlag & (128);
  191. if(newmask != 128)
  192. //is a new avatar?
  193. //if it is then we don't need to tell it about updates as it has already received a full update of the scene
  194. {
  195. //but if it is not then we add to its updatelist
  196. avatar2.TerseUpdateList.Add(this.CreateTerseBlock(avatar));
  197. }
  198. }
  199. }
  200. }
  201. }
  202. }
  203. }
  204. //now reset all update flags
  205. lock(this.RootNode)
  206. {
  207. for (int i = 0; i < this.RootNode.ChildrenCount; i++)
  208. {
  209. this.RootNode.GetChild(i).UpdateFlag = 0;
  210. }
  211. }
  212. this._agentManager.SendTerseUpdateLists();
  213. }
  214. public void AvatarMovementCommand(NetworkInfo userInfo, AgentUpdatePacket updatePacket)
  215. {
  216. uint mask = updatePacket.AgentData.ControlFlags & (1);
  217. AvatarData avatar = _agentManager.GetAgent(userInfo.User.AgentID).Avatar;
  218. if (avatar != null)
  219. {
  220. if (avatar.Started)
  221. {
  222. if (mask == (1))
  223. {
  224. if (!avatar.Walk)
  225. {
  226. UpdateCommand newCommand = new UpdateCommand();
  227. newCommand.CommandType = 1;
  228. newCommand.SObject = avatar;
  229. //start walking
  230. Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0);
  231. Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(updatePacket.AgentData.BodyRotation.W, updatePacket.AgentData.BodyRotation.X, updatePacket.AgentData.BodyRotation.Y, updatePacket.AgentData.BodyRotation.Z);
  232. Axiom.MathLib.Vector3 direc = q * v3;
  233. direc.Normalize();
  234. Axiom.MathLib.Vector3 internDirec = new Vector3(direc.x, direc.y, direc.z);
  235. //work out velocity for sim physics system
  236. direc = direc * ((0.03f) * 128f);
  237. //because of us using a frame based system we can't update the avatar directly
  238. //so we need to add the command to the list and let the update loop deal with it
  239. newCommand.Velocity = new libsecondlife.LLVector3(0, 0 , 0);
  240. newCommand.Velocity.X = direc.x;
  241. newCommand.Velocity.Y = direc.y;
  242. newCommand.Velocity.Z = direc.z;
  243. //work out velocity for clients movement commands
  244. internDirec = internDirec * (0.03f);
  245. internDirec.x += 1;
  246. internDirec.y += 1;
  247. internDirec.z += 1;
  248. newCommand.InternVelocityX = (ushort)(32768 * internDirec.x);
  249. newCommand.InternVelocityY = (ushort)(32768 * internDirec.y);
  250. newCommand.InternVelocityZ = (ushort)(32768 * internDirec.z);
  251. lock(this.Commands)
  252. {
  253. this.Commands.Enqueue(newCommand);
  254. }
  255. }
  256. }
  257. else
  258. {
  259. if (avatar.Walk)
  260. {
  261. UpdateCommand newCommand = new UpdateCommand();
  262. newCommand.CommandType = 1;
  263. newCommand.SObject = avatar;
  264. //walking but key not pressed so need to stop
  265. newCommand.Velocity.X = 0;
  266. newCommand.Velocity.Y = 0;
  267. newCommand.Velocity.Z = 0;
  268. newCommand.InternVelocityX = (ushort)(32768 );
  269. newCommand.InternVelocityY = (ushort)(32768 );
  270. newCommand.InternVelocityZ = (ushort)(32768 );
  271. lock(this.Commands)
  272. {
  273. this.Commands.Enqueue(newCommand);
  274. }
  275. }
  276. }
  277. }
  278. }
  279. }
  280. #region send terrain data
  281. /// <summary>
  282. ///
  283. /// </summary>
  284. /// <param name="userInfo"></param>
  285. public void SendTerrainData(NetworkInfo userInfo)
  286. {
  287. lock(this._sendTerrainSync)
  288. {
  289. string data_path = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory ,"layer_data" );
  290. //send layerdata
  291. LayerDataPacket layerpack = new LayerDataPacket();
  292. layerpack.LayerID.Type = 76;
  293. this.SendLayerData(userInfo, layerpack, Path.Combine(data_path,"layerdata0.dat"));
  294. Console.WriteLine("Sent terrain data");
  295. //test
  296. //this.SendAvatarData(userInfo);
  297. }
  298. }
  299. /// <summary>
  300. ///
  301. /// </summary>
  302. /// <param name="userInfo"></param>
  303. /// <param name="layer"></param>
  304. /// <param name="name"></param>
  305. private void SendLayerData(NetworkInfo userInfo, LayerDataPacket layer, string fileName)
  306. {
  307. FileInfo fInfo = new FileInfo(fileName);
  308. long numBytes = fInfo.Length;
  309. FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
  310. BinaryReader br = new BinaryReader(fStream);
  311. byte [] data1 = br.ReadBytes((int)numBytes);
  312. br.Close();
  313. fStream.Close();
  314. layer.LayerData.Data = data1;
  315. _server.SendPacket(layer, true, userInfo);
  316. }
  317. #endregion
  318. public void AgentCompletingMove(NetworkInfo userInfo)
  319. {
  320. libsecondlife.Packets.AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
  321. mov.AgentData.SessionID = userInfo.User.SessionID;
  322. mov.AgentData.AgentID = userInfo.User.AgentID;
  323. mov.Data.RegionHandle = Globals.Instance.RegionHandle;
  324. mov.Data.Timestamp = 1169838966;
  325. mov.Data.Position = new LLVector3(100f, 100f, 22f);
  326. mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
  327. _server.SendPacket(mov, true, userInfo);
  328. }
  329. public void AddNewAvatar(AvatarData avatar)
  330. {
  331. Console.WriteLine("adding avatar to scene");
  332. lock(this.RootNode)
  333. {
  334. avatar.SceneName = "Avatar" + this._objectCount.ToString("00000");
  335. avatar.Position = new LLVector3(100f, 100f, 22f);
  336. this._objectCount++;
  337. this.RootNode.AddChild(avatar);
  338. }
  339. avatar.UpdateFlag = 128;
  340. //add to new clients list?
  341. }
  342. public void AddNewPrim(PrimData prim)
  343. {
  344. lock(this.RootNode)
  345. {
  346. prim.SceneName = "Prim" + this._objectCount.ToString("00000"); //not sure why still doing this as its not used
  347. this._objectCount++;
  348. this.RootNode.AddChild(prim);
  349. }
  350. prim.UpdateFlag = 64;
  351. }
  352. #region temporary template
  353. //temporary only
  354. private void SetupAvatarTemplate(string name)
  355. {
  356. //should be replaced with completely code generated packets
  357. int i = 0;
  358. FileInfo fInfo = new FileInfo(name);
  359. long numBytes = fInfo.Length;
  360. FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read);
  361. BinaryReader br = new BinaryReader(fStream);
  362. byte [] data1 = br.ReadBytes((int)numBytes);
  363. br.Close();
  364. fStream.Close();
  365. libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
  366. System.Text.Encoding enc = System.Text.Encoding.ASCII;
  367. libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
  368. pos.X = 100f;
  369. objdata.ID = 8880000;
  370. objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
  371. libsecondlife.LLVector3 pos2 = new LLVector3(13.981f,100.0f,20.0f);
  372. //objdata.FullID=user.AgentID;
  373. byte[] pb = pos.GetBytes();
  374. Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
  375. _avatarTemplate = objdata;
  376. }
  377. //really really need to get rid of these templates
  378. public void SetupObjectTemplate(string name)
  379. {
  380. int i = 0;
  381. FileInfo fInfo = new FileInfo(name);
  382. long numBytes = fInfo.Length;
  383. FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read);
  384. BinaryReader br = new BinaryReader(fStream);
  385. byte [] data1 = br.ReadBytes((int)numBytes);
  386. br.Close();
  387. fStream.Close();
  388. libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1,ref i);
  389. this.PrimTemplate = objdata;
  390. objdata.UpdateFlags = objdata.UpdateFlags + 12 - 16 + 32 + 256;
  391. objdata.OwnerID = new LLUUID("00000000-0000-0000-0000-000000000000");
  392. //test adding a new texture to object , to test image downloading
  393. }
  394. #endregion
  395. private void SendAvatarDataToAll(AvatarData avatar)
  396. {
  397. Console.WriteLine("sending avatar data");
  398. ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
  399. objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
  400. objupdate.RegionData.TimeDilation = 0;
  401. objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
  402. objupdate.ObjectData[0] = _avatarTemplate;
  403. objupdate.ObjectData[0].ID = avatar.LocalID;
  404. objupdate.ObjectData[0].FullID = avatar.NetInfo.User.AgentID;
  405. objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + avatar.NetInfo.User.FirstName + "\nLastName STRING RW SV " + avatar.NetInfo.User.LastName + " \0");
  406. libsecondlife.LLVector3 pos2 = avatar.Position;
  407. byte[] pb = pos2.GetBytes();
  408. Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
  409. SendInfo send = new SendInfo();
  410. send.Incr = true;
  411. send.NetInfo = avatar.NetInfo;
  412. send.Packet = objupdate;
  413. send.SentTo = 1; //to all clients
  414. this._updateSender.SendList.Enqueue(send);
  415. }
  416. public void SendCompleteSceneTo(AvatarData avatar)
  417. {
  418. }
  419. public void SendPrimToAll(PrimData prim)
  420. {
  421. PrimData PData = prim;
  422. ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
  423. objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
  424. objupdate.RegionData.TimeDilation = 0;
  425. objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
  426. objupdate.ObjectData[0] = this.PrimTemplate;
  427. objupdate.ObjectData[0].OwnerID = PData.OwnerID;
  428. objupdate.ObjectData[0].PCode = PData.PCode;
  429. objupdate.ObjectData[0].PathBegin = PData.PathBegin;
  430. objupdate.ObjectData[0].PathEnd = PData.PathEnd;
  431. objupdate.ObjectData[0].PathScaleX = PData.PathScaleX;
  432. objupdate.ObjectData[0].PathScaleY = PData.PathScaleY;
  433. objupdate.ObjectData[0].PathShearX = PData.PathShearX;
  434. objupdate.ObjectData[0].PathShearY = PData.PathShearY;
  435. objupdate.ObjectData[0].PathSkew = PData.PathSkew;
  436. objupdate.ObjectData[0].ProfileBegin = PData.ProfileBegin;
  437. objupdate.ObjectData[0].ProfileEnd = PData.ProfileEnd;
  438. objupdate.ObjectData[0].Scale = PData.Scale;
  439. objupdate.ObjectData[0].PathCurve = PData.PathCurve;
  440. objupdate.ObjectData[0].ProfileCurve = PData.ProfileCurve;
  441. objupdate.ObjectData[0].ParentID = PData.ParentID ;
  442. objupdate.ObjectData[0].ProfileHollow = PData.ProfileHollow ;
  443. objupdate.ObjectData[0].TextureEntry = PData.Texture.ToBytes();
  444. objupdate.ObjectData[0].ID = PData.LocalID;
  445. objupdate.ObjectData[0].FullID = PData.FullID;
  446. //update position
  447. byte[] pb = PData.Position.GetBytes();
  448. Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length);
  449. SendInfo send = new SendInfo();
  450. send.Incr = true;
  451. send.NetInfo = null;
  452. send.Packet = objupdate;
  453. send.SentTo = 1; //to all clients
  454. this._updateSender.SendList.Enqueue(send);
  455. }
  456. public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateTerseBlock(AvatarData avatar)
  457. {
  458. byte[] bytes = new byte[60];
  459. int i=0;
  460. ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
  461. dat.TextureEntry = _avatarTemplate.TextureEntry;
  462. libsecondlife.LLVector3 pos2 = new LLVector3(avatar.Position.X, avatar.Position.Y, avatar.Position.Z);
  463. uint ID = avatar.LocalID;
  464. bytes[i++] = (byte)(ID % 256);
  465. bytes[i++] = (byte)((ID >> 8) % 256);
  466. bytes[i++] = (byte)((ID >> 16) % 256);
  467. bytes[i++] = (byte)((ID >> 24) % 256);
  468. bytes[i++] = 0;
  469. bytes[i++] = 1;
  470. i += 14;
  471. bytes[i++] = 128;
  472. bytes[i++] = 63;
  473. byte[] pb = pos2.GetBytes();
  474. Array.Copy(pb, 0, bytes, i, pb.Length);
  475. i += 12;
  476. ushort ac = 32767;
  477. bytes[i++] = (byte)(avatar.InternVelocityX % 256);
  478. bytes[i++] = (byte)((avatar.InternVelocityX >> 8) % 256);
  479. bytes[i++] = (byte)(avatar.InternVelocityY % 256);
  480. bytes[i++] = (byte)((avatar.InternVelocityY>> 8) % 256);
  481. bytes[i++] = (byte)(avatar.InternVelocityZ % 256);
  482. bytes[i++] = (byte)((avatar.InternVelocityZ >> 8) % 256);
  483. //accel
  484. bytes[i++] = (byte)(ac % 256);
  485. bytes[i++] = (byte)((ac >> 8) % 256);
  486. bytes[i++] = (byte)(ac % 256);
  487. bytes[i++] = (byte)((ac >> 8) % 256);
  488. bytes[i++] = (byte)(ac % 256);
  489. bytes[i++] = (byte)((ac >> 8) % 256);
  490. //rot
  491. bytes[i++] = (byte)(ac % 256);
  492. bytes[i++] = (byte)((ac >> 8) % 256);
  493. bytes[i++] = (byte)(ac % 256);
  494. bytes[i++] = (byte)((ac >> 8) % 256);
  495. bytes[i++] = (byte)(ac % 256);
  496. bytes[i++] = (byte)((ac >> 8) % 256);
  497. bytes[i++] = (byte)(ac % 256);
  498. bytes[i++] = (byte)((ac >> 8) % 256);
  499. //rotation vel
  500. bytes[i++] = (byte)(ac % 256);
  501. bytes[i++] = (byte)((ac >> 8) % 256);
  502. bytes[i++] = (byte)(ac % 256);
  503. bytes[i++] = (byte)((ac >> 8) % 256);
  504. bytes[i++] = (byte)(ac % 256);
  505. bytes[i++] = (byte)((ac >> 8) % 256);
  506. dat.Data=bytes;
  507. return(dat);
  508. }
  509. public void SendAvatarAppearanceToAllExcept(AvatarData avatar)
  510. {
  511. AvatarAppearancePacket avp = new AvatarAppearancePacket();
  512. avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
  513. //avp.ObjectData.TextureEntry=this.avatar_template.TextureEntry;// br.ReadBytes((int)numBytes);
  514. FileInfo fInfo = new FileInfo("Avatar_texture3.dat");
  515. long numBytes = fInfo.Length;
  516. FileStream fStream = new FileStream("Avatar_texture3.dat", FileMode.Open, FileAccess.Read);
  517. BinaryReader br = new BinaryReader(fStream);
  518. avp.ObjectData.TextureEntry = br.ReadBytes((int)numBytes);
  519. br.Close();
  520. fStream.Close();
  521. AvatarAppearancePacket.VisualParamBlock avblock = null;
  522. for(int i = 0; i < 218; i++)
  523. {
  524. avblock = new AvatarAppearancePacket.VisualParamBlock();
  525. avblock.ParamValue = (byte)avatar.VisParams.Params[i];
  526. avp.VisualParam[i] = avblock;
  527. }
  528. avp.Sender.IsTrial = false;
  529. avp.Sender.ID = avatar.NetInfo.User.AgentID;
  530. SendInfo send = new SendInfo();
  531. send.Incr = true;
  532. send.NetInfo = avatar.NetInfo;
  533. send.Packet = avp;
  534. send.SentTo = 2; //to all clients except avatar
  535. this._updateSender.SendList.Enqueue(send);
  536. }
  537. }
  538. //any need for separate nodes and sceneobjects?
  539. //do we need multiple objects in the same node?
  540. public class Node
  541. {
  542. private List<Node> _children;
  543. //private List<SceneObject> _attached;
  544. public byte SceneType;
  545. public string SceneName;
  546. public LLVector3 Position;
  547. public LLVector3 Velocity = new LLVector3(0,0,0);
  548. public byte UpdateFlag;
  549. public ushort InternVelocityX = 32768;
  550. public ushort InternVelocityY = 32768;
  551. public ushort InternVelocityZ = 32768;
  552. public List<Node> ChildNodes
  553. {
  554. get
  555. {
  556. return(_children);
  557. }
  558. }
  559. public int ChildrenCount
  560. {
  561. get
  562. {
  563. return(_children.Count);
  564. }
  565. }
  566. /*
  567. public List<SceneObject> AttachedObjexts
  568. {
  569. get
  570. {
  571. return(_attached);
  572. }
  573. }
  574. */
  575. public Node()
  576. {
  577. _children = new List<Node>();
  578. //_attached = new List<SceneObject>();
  579. }
  580. /*
  581. /// <summary>
  582. ///
  583. /// </summary>
  584. /// <param name="index"></param>
  585. /// <returns></returns>
  586. public SceneObject GetAttachedObject(int index)
  587. {
  588. if(_attached.Count > index)
  589. {
  590. return(_attached[index]);
  591. }
  592. else
  593. {
  594. return(null);
  595. }
  596. }
  597. /// <summary>
  598. ///
  599. /// </summary>
  600. /// <param name="sceneObject"></param>
  601. public void AttachObject(SceneObject sceneObject)
  602. {
  603. _attached.Add(sceneObject);
  604. }
  605. /// <summary>
  606. ///
  607. /// </summary>
  608. /// <param name="sceneObject"></param>
  609. public void RemoveObject(SceneObject sceneObject)
  610. {
  611. _attached.Remove(sceneObject);
  612. }
  613. /// <summary>
  614. ///
  615. /// </summary>
  616. /// <param name="sceneObject"></param>
  617. /// <returns></returns>
  618. public int HasAttachedObject(SceneObject sceneObject)
  619. {
  620. int rValue = -1;
  621. for(int i = 0; i < this._attached.Count; i++)
  622. {
  623. if(sceneObject == this._attached[i])
  624. {
  625. rValue = i;
  626. }
  627. }
  628. return(rValue);
  629. }
  630. */
  631. /// <summary>
  632. ///
  633. /// </summary>
  634. /// <param name="index"></param>
  635. /// <returns></returns>
  636. public Node GetChild(int index)
  637. {
  638. if(_children.Count > index)
  639. {
  640. return(_children[index]);
  641. }
  642. else
  643. {
  644. return(null);
  645. }
  646. }
  647. /// <summary>
  648. ///
  649. /// </summary>
  650. /// <param name="node"></param>
  651. public void AddChild(Node node)
  652. {
  653. _children.Add(node);
  654. }
  655. /// <summary>
  656. ///
  657. /// </summary>
  658. /// <param name="node"></param>
  659. public void RemoveChild(Node node)
  660. {
  661. _children.Remove(node);
  662. }
  663. }
  664. /*
  665. public class SceneObject
  666. {
  667. public byte SceneType;
  668. public string SceneName;
  669. public SceneObject()
  670. {
  671. }
  672. }*/
  673. public class Terrain
  674. {
  675. public List<LLVector3> Vertices;
  676. public List<Face> Faces;
  677. public Terrain()
  678. {
  679. Vertices = new List<LLVector3>();
  680. Faces = new List<Face>();
  681. }
  682. public LLVector3 CastRay()
  683. {
  684. return(new LLVector3(0,0,0));
  685. }
  686. }
  687. public struct Face
  688. {
  689. public int V1;
  690. public int V2;
  691. public int V3;
  692. }
  693. public class UpdateCommand
  694. {
  695. public byte CommandType;
  696. public Node SObject;
  697. public LLVector3 Position;
  698. public LLVector3 Velocity;
  699. public ushort InternVelocityX;
  700. public ushort InternVelocityY;
  701. public ushort InternVelocityZ;
  702. public LLQuaternion Rotation;
  703. public UpdateCommand()
  704. {
  705. }
  706. }
  707. public class UpdateSender
  708. {
  709. public BlockingQueue<SendInfo> SendList;
  710. private Thread _mthread;
  711. private Server _server;
  712. private AgentManager _agentManager;
  713. public UpdateSender(Server server, AgentManager agentManager)
  714. {
  715. SendList = new BlockingQueue<SendInfo>();
  716. _server = server;
  717. _agentManager = agentManager;
  718. }
  719. public void Startup()
  720. {
  721. _mthread = new Thread(new System.Threading.ThreadStart(RunSender));
  722. _mthread.IsBackground = true;
  723. _mthread.Start();
  724. }
  725. private void RunSender()
  726. {
  727. //process SendList and send packets to clients
  728. try
  729. {
  730. for(;;)
  731. {
  732. SendInfo sendInfo;
  733. sendInfo = this.SendList.Dequeue();
  734. switch(sendInfo.SentTo)
  735. {
  736. case 0:
  737. this._server.SendPacket(sendInfo.Packet, sendInfo.Incr, sendInfo.NetInfo);
  738. break;
  739. case 1:
  740. this._agentManager.SendPacketToALL(sendInfo.Packet);
  741. break;
  742. case 2:
  743. this._agentManager.SendPacketToAllExcept(sendInfo.Packet, sendInfo.NetInfo.User.AgentID);
  744. break;
  745. default:
  746. break;
  747. }
  748. }
  749. }
  750. catch (Exception e)
  751. {
  752. Console.WriteLine(e.Message);
  753. }
  754. }
  755. }
  756. public class SendInfo
  757. {
  758. public Packet Packet;
  759. public bool Incr = true;
  760. public NetworkInfo NetInfo;
  761. public byte SentTo = 0; // 0 just this client, 1 to all clients, 2 to all except this client.
  762. public SendInfo()
  763. {
  764. }
  765. }
  766. }