aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim.RegionServer/world/Primitive.cs
diff options
context:
space:
mode:
authorgareth2007-03-22 10:11:15 +0000
committergareth2007-03-22 10:11:15 +0000
commit7daa3955bc3a1918e40962851f9e8d38597a245e (patch)
treebee3e1372a7eed0c1b220a8a49f7bee7d29a6b91 /OpenSim.RegionServer/world/Primitive.cs
parentLoad XML for neighbourinfo from grid (diff)
downloadopensim-SC_OLD-7daa3955bc3a1918e40962851f9e8d38597a245e.zip
opensim-SC_OLD-7daa3955bc3a1918e40962851f9e8d38597a245e.tar.gz
opensim-SC_OLD-7daa3955bc3a1918e40962851f9e8d38597a245e.tar.bz2
opensim-SC_OLD-7daa3955bc3a1918e40962851f9e8d38597a245e.tar.xz
brought zircon branch into trunk
Diffstat (limited to '')
-rw-r--r--OpenSim.RegionServer/world/Primitive.cs485
1 files changed, 485 insertions, 0 deletions
diff --git a/OpenSim.RegionServer/world/Primitive.cs b/OpenSim.RegionServer/world/Primitive.cs
new file mode 100644
index 0000000..b190d81
--- /dev/null
+++ b/OpenSim.RegionServer/world/Primitive.cs
@@ -0,0 +1,485 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using OpenSim.types;
5using libsecondlife;
6using libsecondlife.Packets;
7using OpenSim.Framework.Interfaces;
8using OpenSim.Physics.Manager;
9using OpenSim.Framework.Assets;
10
11namespace OpenSim.world
12{
13 public class Primitive : Entity
14 {
15 protected float mesh_cutbegin;
16 protected float mesh_cutend;
17 protected PrimData primData;
18 protected bool newPrimFlag = false;
19 protected bool updateFlag = false;
20 protected bool dirtyFlag = false;
21 private ObjectUpdatePacket OurPacket;
22 private PhysicsActor _physActor;
23 private bool physicsEnabled = false;
24 private bool physicstest = false; //just added for testing
25
26 public bool PhysicsEnabled
27 {
28 get
29 {
30 return physicsEnabled;
31 }
32 set
33 {
34 physicsEnabled = value;
35 }
36 }
37 public bool UpdateFlag
38 {
39 get
40 {
41 return updateFlag;
42 }
43 set
44 {
45 updateFlag = value;
46 }
47 }
48 public LLVector3 Scale
49 {
50 set
51 {
52 this.primData.Scale = value;
53 this.dirtyFlag = true;
54 }
55 get
56 {
57 return this.primData.Scale;
58 }
59 }
60 public PhysicsActor PhysActor
61 {
62 set
63 {
64 this._physActor = value;
65 }
66 }
67
68 public Primitive()
69 {
70 mesh_cutbegin = 0.0f;
71 mesh_cutend = 1.0f;
72 }
73
74 public override Mesh getMesh()
75 {
76 Mesh mesh = new Mesh();
77 Triangle tri = new Triangle(
78 new Axiom.MathLib.Vector3(0.0f, 1.0f, 1.0f),
79 new Axiom.MathLib.Vector3(1.0f, 0.0f, 1.0f),
80 new Axiom.MathLib.Vector3(1.0f, 1.0f, 0.0f));
81
82 mesh.AddTri(tri);
83 mesh += base.getMesh();
84
85 return mesh;
86 }
87
88 public void UpdatePosition(LLVector3 pos)
89 {
90 this.position = pos;
91 if (this._physActor != null) // && this.physicsEnabled)
92 {
93 this._physActor.Position = new PhysicsVector(pos.X, pos.Y, pos.Z);
94 }
95 this.updateFlag = true;
96 }
97
98 public override void update()
99 {
100 if (this.newPrimFlag)
101 {
102 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
103 {
104 client.OutPacket(OurPacket);
105 }
106 this.newPrimFlag = false;
107 }
108 else if (this.updateFlag)
109 {
110 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
111 terse.RegionData.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle; // FIXME
112 terse.RegionData.TimeDilation = 64096;
113 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
114 terse.ObjectData[0] = this.CreateImprovedBlock();
115 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
116 {
117 client.OutPacket(terse);
118 }
119 this.updateFlag = false;
120 }
121 else if (this.dirtyFlag)
122 {
123 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
124 {
125 UpdateClient(client);
126 }
127 this.dirtyFlag = false;
128 }
129 else
130 {
131 if (this._physActor != null && this.physicsEnabled)
132 {
133 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
134 terse.RegionData.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle; // FIXME
135 terse.RegionData.TimeDilation = 64096;
136 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
137 terse.ObjectData[0] = this.CreateImprovedBlock();
138 foreach (SimClient client in OpenSimRoot.Instance.ClientThreads.Values)
139 {
140 client.OutPacket(terse);
141 }
142 }
143 }
144
145 if (this.physicstest)
146 {
147 LLVector3 pos = this.position;
148 pos.Z += 0.0001f;
149 this.UpdatePosition(pos);
150 this.physicstest = false;
151 }
152 }
153
154 public void UpdateClient(SimClient RemoteClient)
155 {
156
157 LLVector3 lPos;
158 if (this._physActor != null && this.physicsEnabled)
159 {
160 PhysicsVector pPos = this._physActor.Position;
161 lPos = new LLVector3(pPos.X, pPos.Y, pPos.Z);
162 }
163 else
164 {
165 lPos = this.position;
166 }
167 byte[] pb = lPos.GetBytes();
168 Array.Copy(pb, 0, OurPacket.ObjectData[0].ObjectData, 0, pb.Length);
169
170 // OurPacket should be update with the follwing in updateShape() rather than having to do it here
171 OurPacket.ObjectData[0].OwnerID = this.primData.OwnerID;
172 OurPacket.ObjectData[0].PCode = this.primData.PCode;
173 OurPacket.ObjectData[0].PathBegin = this.primData.PathBegin;
174 OurPacket.ObjectData[0].PathEnd = this.primData.PathEnd;
175 OurPacket.ObjectData[0].PathScaleX = this.primData.PathScaleX;
176 OurPacket.ObjectData[0].PathScaleY = this.primData.PathScaleY;
177 OurPacket.ObjectData[0].PathShearX = this.primData.PathShearX;
178 OurPacket.ObjectData[0].PathShearY = this.primData.PathShearY;
179 OurPacket.ObjectData[0].PathSkew = this.primData.PathSkew;
180 OurPacket.ObjectData[0].ProfileBegin = this.primData.ProfileBegin;
181 OurPacket.ObjectData[0].ProfileEnd = this.primData.ProfileEnd;
182 OurPacket.ObjectData[0].Scale = this.primData.Scale;
183 OurPacket.ObjectData[0].PathCurve = this.primData.PathCurve;
184 OurPacket.ObjectData[0].ProfileCurve = this.primData.ProfileCurve;
185 OurPacket.ObjectData[0].ParentID = 0;
186 OurPacket.ObjectData[0].ProfileHollow = this.primData.ProfileHollow;
187 //finish off copying rest of shape data
188 OurPacket.ObjectData[0].PathRadiusOffset = this.primData.PathRadiusOffset;
189 OurPacket.ObjectData[0].PathRevolutions = this.primData.PathRevolutions;
190 OurPacket.ObjectData[0].PathTaperX = this.primData.PathTaperX;
191 OurPacket.ObjectData[0].PathTaperY = this.primData.PathTaperY;
192 OurPacket.ObjectData[0].PathTwist = this.primData.PathTwist;
193 OurPacket.ObjectData[0].PathTwistBegin = this.primData.PathTwistBegin;
194
195 RemoteClient.OutPacket(OurPacket);
196 }
197
198 public void UpdateShape(ObjectShapePacket.ObjectDataBlock addPacket)
199 {
200 this.primData.PathBegin = addPacket.PathBegin;
201 this.primData.PathEnd = addPacket.PathEnd;
202 this.primData.PathScaleX = addPacket.PathScaleX;
203 this.primData.PathScaleY = addPacket.PathScaleY;
204 this.primData.PathShearX = addPacket.PathShearX;
205 this.primData.PathShearY = addPacket.PathShearY;
206 this.primData.PathSkew = addPacket.PathSkew;
207 this.primData.ProfileBegin = addPacket.ProfileBegin;
208 this.primData.ProfileEnd = addPacket.ProfileEnd;
209 this.primData.PathCurve = addPacket.PathCurve;
210 this.primData.ProfileCurve = addPacket.ProfileCurve;
211 this.primData.ProfileHollow = addPacket.ProfileHollow;
212 this.primData.PathRadiusOffset = addPacket.PathRadiusOffset;
213 this.primData.PathRevolutions = addPacket.PathRevolutions;
214 this.primData.PathTaperX = addPacket.PathTaperX;
215 this.primData.PathTaperY = addPacket.PathTaperY;
216 this.primData.PathTwist = addPacket.PathTwist;
217 this.primData.PathTwistBegin = addPacket.PathTwistBegin;
218 this.dirtyFlag = true;
219 }
220
221 public void UpdateTexture(byte[] tex)
222 {
223 this.primData.Texture = this.OurPacket.ObjectData[0].TextureEntry = tex;
224 this.dirtyFlag = true;
225 }
226
227 public void UpdateObjectFlags(ObjectFlagUpdatePacket pack)
228 {
229 if (this._physActor != null)
230 {
231 if (this._physActor.Kinematic == pack.AgentData.UsePhysics)
232 {
233 this._physActor.Kinematic = !pack.AgentData.UsePhysics; //if Usephysics = true, then Kinematic should = false
234 }
235 this.physicsEnabled = pack.AgentData.UsePhysics;
236 if (this._physActor.Kinematic == false)
237 {
238 LLVector3 pos = this.position;
239 this.UpdatePosition(pos);
240 pos.Z += 0.000001f;
241 this.UpdatePosition(pos);
242 this.physicstest = true;
243 }
244 else
245 {
246 PhysicsVector vec = this._physActor.Position;
247 LLVector3 pos = new LLVector3(vec.X, vec.Y, vec.Z);
248 this.position = pos;
249 this.updateFlag = true;
250 }
251 }
252 }
253
254 public void CreateFromPacket(ObjectAddPacket addPacket, LLUUID agentID, uint localID)
255 {
256 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
257 objupdate.RegionData.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle;
258 objupdate.RegionData.TimeDilation = 64096;
259
260 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
261 PrimData PData = new PrimData();
262 this.primData = PData;
263 objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
264 objupdate.ObjectData[0].PSBlock = new byte[0];
265 objupdate.ObjectData[0].ExtraParams = new byte[1];
266 objupdate.ObjectData[0].MediaURL = new byte[0];
267 objupdate.ObjectData[0].NameValue = new byte[0];
268 objupdate.ObjectData[0].Text = new byte[0];
269 objupdate.ObjectData[0].TextColor = new byte[4];
270 objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0);
271 objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0);
272 objupdate.ObjectData[0].Material = 3;
273 objupdate.ObjectData[0].UpdateFlags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456;
274 objupdate.ObjectData[0].TextureAnim = new byte[0];
275 objupdate.ObjectData[0].Sound = LLUUID.Zero;
276 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
277 objupdate.ObjectData[0].TextureEntry = ntex.ToBytes();
278 objupdate.ObjectData[0].State = 0;
279 objupdate.ObjectData[0].Data = new byte[0];
280 PData.OwnerID = objupdate.ObjectData[0].OwnerID = agentID;
281 PData.PCode = objupdate.ObjectData[0].PCode = addPacket.ObjectData.PCode;
282 PData.PathBegin = objupdate.ObjectData[0].PathBegin = addPacket.ObjectData.PathBegin;
283 PData.PathEnd = objupdate.ObjectData[0].PathEnd = addPacket.ObjectData.PathEnd;
284 PData.PathScaleX = objupdate.ObjectData[0].PathScaleX = addPacket.ObjectData.PathScaleX;
285 PData.PathScaleY = objupdate.ObjectData[0].PathScaleY = addPacket.ObjectData.PathScaleY;
286 PData.PathShearX = objupdate.ObjectData[0].PathShearX = addPacket.ObjectData.PathShearX;
287 PData.PathShearY = objupdate.ObjectData[0].PathShearY = addPacket.ObjectData.PathShearY;
288 PData.PathSkew = objupdate.ObjectData[0].PathSkew = addPacket.ObjectData.PathSkew;
289 PData.ProfileBegin = objupdate.ObjectData[0].ProfileBegin = addPacket.ObjectData.ProfileBegin;
290 PData.ProfileEnd = objupdate.ObjectData[0].ProfileEnd = addPacket.ObjectData.ProfileEnd;
291 PData.Scale = objupdate.ObjectData[0].Scale = addPacket.ObjectData.Scale;
292 PData.PathCurve = objupdate.ObjectData[0].PathCurve = addPacket.ObjectData.PathCurve;
293 PData.ProfileCurve = objupdate.ObjectData[0].ProfileCurve = addPacket.ObjectData.ProfileCurve;
294 PData.ParentID = objupdate.ObjectData[0].ParentID = 0;
295 PData.ProfileHollow = objupdate.ObjectData[0].ProfileHollow = addPacket.ObjectData.ProfileHollow;
296
297 PData.PathRadiusOffset = objupdate.ObjectData[0].PathRadiusOffset = addPacket.ObjectData.PathRadiusOffset;
298 PData.PathRevolutions = objupdate.ObjectData[0].PathRevolutions = addPacket.ObjectData.PathRevolutions;
299 PData.PathTaperX = objupdate.ObjectData[0].PathTaperX = addPacket.ObjectData.PathTaperX;
300 PData.PathTaperY = objupdate.ObjectData[0].PathTaperY = addPacket.ObjectData.PathTaperY;
301 PData.PathTwist = objupdate.ObjectData[0].PathTwist = addPacket.ObjectData.PathTwist;
302 PData.PathTwistBegin = objupdate.ObjectData[0].PathTwistBegin = addPacket.ObjectData.PathTwistBegin;
303
304 objupdate.ObjectData[0].ID = (uint)(localID);
305 objupdate.ObjectData[0].FullID = new LLUUID("edba7151-5857-acc5-b30b-f01efef" + (localID - 702000).ToString("00000"));
306 objupdate.ObjectData[0].ObjectData = new byte[60];
307 objupdate.ObjectData[0].ObjectData[46] = 128;
308 objupdate.ObjectData[0].ObjectData[47] = 63;
309 LLVector3 pos1 = addPacket.ObjectData.RayEnd;
310 //update position
311 byte[] pb = pos1.GetBytes();
312 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length);
313
314 this.newPrimFlag = true;
315 this.uuid = objupdate.ObjectData[0].FullID;
316 this.localid = objupdate.ObjectData[0].ID;
317 this.position = pos1;
318 this.OurPacket = objupdate;
319 }
320
321 public void CreateFromStorage(PrimData store)
322 {
323 //need to clean this up as it shares a lot of code with CreateFromPacket()
324 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
325 objupdate.RegionData.RegionHandle = OpenSimRoot.Instance.Cfg.RegionHandle;
326 objupdate.RegionData.TimeDilation = 64096;
327 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
328
329 this.primData = store;
330 objupdate.ObjectData[0] = new ObjectUpdatePacket.ObjectDataBlock();
331 objupdate.ObjectData[0].PSBlock = new byte[0];
332 objupdate.ObjectData[0].ExtraParams = new byte[1];
333 objupdate.ObjectData[0].MediaURL = new byte[0];
334 objupdate.ObjectData[0].NameValue = new byte[0];
335 objupdate.ObjectData[0].Text = new byte[0];
336 objupdate.ObjectData[0].TextColor = new byte[4];
337 objupdate.ObjectData[0].JointAxisOrAnchor = new LLVector3(0, 0, 0);
338 objupdate.ObjectData[0].JointPivot = new LLVector3(0, 0, 0);
339 objupdate.ObjectData[0].Material = 3;
340 objupdate.ObjectData[0].UpdateFlags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456;
341 objupdate.ObjectData[0].TextureAnim = new byte[0];
342 objupdate.ObjectData[0].Sound = LLUUID.Zero;
343
344 if (store.Texture == null)
345 {
346 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
347 objupdate.ObjectData[0].TextureEntry = ntex.ToBytes();
348 }
349 else
350 {
351 objupdate.ObjectData[0].TextureEntry = store.Texture;
352 }
353
354 objupdate.ObjectData[0].State = 0;
355 objupdate.ObjectData[0].Data = new byte[0];
356 objupdate.ObjectData[0].OwnerID = this.primData.OwnerID;
357 objupdate.ObjectData[0].PCode = this.primData.PCode;
358 objupdate.ObjectData[0].PathBegin = this.primData.PathBegin;
359 objupdate.ObjectData[0].PathEnd = this.primData.PathEnd;
360 objupdate.ObjectData[0].PathScaleX = this.primData.PathScaleX;
361 objupdate.ObjectData[0].PathScaleY = this.primData.PathScaleY;
362 objupdate.ObjectData[0].PathShearX = this.primData.PathShearX;
363 objupdate.ObjectData[0].PathShearY = this.primData.PathShearY;
364 objupdate.ObjectData[0].PathSkew = this.primData.PathSkew;
365 objupdate.ObjectData[0].ProfileBegin = this.primData.ProfileBegin;
366 objupdate.ObjectData[0].ProfileEnd = this.primData.ProfileEnd;
367 objupdate.ObjectData[0].Scale = this.primData.Scale;
368 objupdate.ObjectData[0].PathCurve = this.primData.PathCurve;
369 objupdate.ObjectData[0].ProfileCurve = this.primData.ProfileCurve;
370 objupdate.ObjectData[0].ParentID = 0;
371 objupdate.ObjectData[0].ProfileHollow = this.primData.ProfileHollow;
372 //finish off copying rest of shape data
373 objupdate.ObjectData[0].PathRadiusOffset = this.primData.PathRadiusOffset;
374 objupdate.ObjectData[0].PathRevolutions = this.primData.PathRevolutions;
375 objupdate.ObjectData[0].PathTaperX = this.primData.PathTaperX;
376 objupdate.ObjectData[0].PathTaperY = this.primData.PathTaperY;
377 objupdate.ObjectData[0].PathTwist = this.primData.PathTwist;
378 objupdate.ObjectData[0].PathTwistBegin = this.primData.PathTwistBegin;
379
380 objupdate.ObjectData[0].ID = (uint)store.LocalID;
381 objupdate.ObjectData[0].FullID = store.FullID;
382
383 objupdate.ObjectData[0].ObjectData = new byte[60];
384 objupdate.ObjectData[0].ObjectData[46] = 128;
385 objupdate.ObjectData[0].ObjectData[47] = 63;
386 LLVector3 pos1 = store.Position;
387 //update position
388 byte[] pb = pos1.GetBytes();
389 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length);
390
391 this.uuid = objupdate.ObjectData[0].FullID;
392 this.localid = objupdate.ObjectData[0].ID;
393 this.position = pos1;
394 this.OurPacket = objupdate;
395
396 }
397 public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedBlock()
398 {
399 uint ID = this.localid;
400 byte[] bytes = new byte[60];
401
402 int i = 0;
403 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
404 dat.TextureEntry = this.OurPacket.ObjectData[0].TextureEntry;
405
406 bytes[i++] = (byte)(ID % 256);
407 bytes[i++] = (byte)((ID >> 8) % 256);
408 bytes[i++] = (byte)((ID >> 16) % 256);
409 bytes[i++] = (byte)((ID >> 24) % 256);
410 bytes[i++] = 0;
411 bytes[i++] = 0;
412
413 LLVector3 lPos;
414 Axiom.MathLib.Quaternion lRot;
415 if (this._physActor != null && this.physicsEnabled)
416 {
417 PhysicsVector pPos = this._physActor.Position;
418 lPos = new LLVector3(pPos.X, pPos.Y, pPos.Z);
419 lRot = this._physActor.Orientation;
420 }
421 else
422 {
423 lPos = this.position;
424 lRot = this.rotation;
425 }
426 byte[] pb = lPos.GetBytes();
427 Array.Copy(pb, 0, bytes, i, pb.Length);
428 i += 12;
429 ushort ac = 32767;
430
431 //vel
432 bytes[i++] = (byte)(ac % 256);
433 bytes[i++] = (byte)((ac >> 8) % 256);
434 bytes[i++] = (byte)(ac % 256);
435 bytes[i++] = (byte)((ac >> 8) % 256);
436 bytes[i++] = (byte)(ac % 256);
437 bytes[i++] = (byte)((ac >> 8) % 256);
438
439 //accel
440 bytes[i++] = (byte)(ac % 256);
441 bytes[i++] = (byte)((ac >> 8) % 256);
442 bytes[i++] = (byte)(ac % 256);
443 bytes[i++] = (byte)((ac >> 8) % 256);
444 bytes[i++] = (byte)(ac % 256);
445 bytes[i++] = (byte)((ac >> 8) % 256);
446
447 ushort rw, rx, ry, rz;
448 rw = (ushort)(32768 * (lRot.w + 1));
449 rx = (ushort)(32768 * (lRot.x + 1));
450 ry = (ushort)(32768 * (lRot.y + 1));
451 rz = (ushort)(32768 * (lRot.z + 1));
452
453 //rot
454 bytes[i++] = (byte)(rx % 256);
455 bytes[i++] = (byte)((rx >> 8) % 256);
456 bytes[i++] = (byte)(ry % 256);
457 bytes[i++] = (byte)((ry >> 8) % 256);
458 bytes[i++] = (byte)(rz % 256);
459 bytes[i++] = (byte)((rz >> 8) % 256);
460 bytes[i++] = (byte)(rw % 256);
461 bytes[i++] = (byte)((rw >> 8) % 256);
462
463 //rotation vel
464 bytes[i++] = (byte)(ac % 256);
465 bytes[i++] = (byte)((ac >> 8) % 256);
466 bytes[i++] = (byte)(ac % 256);
467 bytes[i++] = (byte)((ac >> 8) % 256);
468 bytes[i++] = (byte)(ac % 256);
469 bytes[i++] = (byte)((ac >> 8) % 256);
470
471 dat.Data = bytes;
472 return dat;
473 }
474
475 public override void BackUp()
476 {
477 this.primData.FullID = this.uuid;
478 this.primData.LocalID = this.localid;
479 this.primData.Position = this.position;
480 this.primData.Rotation = new LLQuaternion(this.rotation.x, this.rotation.y, this.rotation.z, this.rotation.w);
481 OpenSimRoot.Instance.LocalWorld.localStorage.StorePrim(this.primData);
482 }
483 }
484
485}