public void AddNode(int oid, ObjectNode objNode)
        {
            NameNode nameNode = new NameNode();
            //			nameNode.nameBar = (StaticText)WindowManager.Instance.CreateWindow(
            //								"WindowsLook.WLStaticText", "Window/LabelText-" + oid);
            //			nameNode.nameBar.Font = font;
            //			nameNode.nameBar.Text = "Name: " + objNode.Name;
            //			nameNode.nameBar.HorizontalFormat = HorizontalTextFormat.Center;
            //			nameNode.nameBar.VerticalFormat = VerticalTextFormat.Top;
            //			nameNode.nameBar.SetTextColor(new Color(1, 0, 0, 0));
            //			nameNode.nameBar.MetricsMode = MetricsMode.Absolute;
            //			float chromeHeight =
            //				nameNode.nameBar.UnclippedPixelRect.Height - nameNode.nameBar.UnclippedInnerRect.Height;
            //			Logger.Log(0, "chromeHeight: {0} Line Spacing: {1}", chromeHeight, font.LineSpacing);
            //			nameNode.nameBar.Size = new Size(60, chromeHeight + font.LineSpacing + 5); // FIXME (why do i need +5)
            nameDictionary[oid] = nameNode;
            //			window.AddChild(nameNode.nameBar);
            //			nameNode.nameBar.MetricsMode = MetricsMode.Relative;

            // Console.WriteLine("Adding node for: " + objNode.Name);
            NameWidget widget = new NameWidget(objNode.SceneNode, objNode.Name);
            widget.Initialize();
            // Object will be clipped to this size
            widget.MetricsMode = MetricsMode.Relative;
            widget.Size = new Size(1.0f, 1.0f);
            widget.Position = new Point(0.0f, 0.0f);
            widget.Text = objNode.Name;
            widget.HorizontalFormat = HorizontalTextFormat.Center;
            widget.VerticalFormat = VerticalTextFormat.Centered;
            widget.Visible = true;
            window.AddChild(widget);
        }
        /// <summary>
        ///   Inform the name manager about an object node for which the name
        ///   should be displayed.
        /// </summary>
        /// <param name="oid">the object id of the node (used as the key for lookups)</param>
        /// <param name="objNode">the object node whose name should be displayed</param>
        public void AddNode(long oid, ObjectNode objNode)
        {
            NameNode widgetNode = new NameNode(oid);
            Node attachNode = null;
            WidgetSceneObject attachObj = new WidgetSceneObject();
            attachObj.WidgetNode = widgetNode;
            AttachmentPoint ap = objNode.GetAttachmentPoint("name-disabled");
            if (ap == null) {
                // Default to a bit larger than the height of the bounding box
                float objectHeight = objNode.Entity.BoundingBox.Size.y * 1.02f;
                ap = new AttachmentPoint("name-disabled", null, Quaternion.Identity, Vector3.UnitY * objectHeight);
            }
            attachNode = objNode.AttachLocalObject(ap, attachObj);
            if (attachNode == null) {
                widgetNode.NodeVisible = true;
                widgetNode.Node = objNode.SceneNode;
            } else {
                // The node visible will be set by the attachObj
                widgetNode.Node = attachNode;
            }

            // FIXME
            //widgetNode.Widget.Text = objNode.Name;
            //widgetNode.Widget.Font = font;
            window.AddChild(widgetNode.Widget);
            widgetNode.Widget.Initialize();
            widgetNode.SetFont(font);
            widgetNode.SetText(objNode.Name);
            lock (nameDictionary) {
                nameDictionary[oid] = widgetNode;
            }
        }
        public void AddNode(int oid, ObjectNode objNode)
        {
            // Create a namebar scene node and entity to handle names
            Axiom.MathLib.Vector3 offset = new Axiom.MathLib.Vector3(0, 2 * Client.OneMeter, 0);
            SceneNode sceneNode = objNode.SceneNode.CreateChildSceneNode("namebar." + oid, offset);
            TexturedBillboardSet widget = new TexturedBillboardSet("billboard." + oid);
            widget.MaterialName = "font-material";
            widget.BillboardType = BillboardType.Point;
            widget.CommonDirection = Axiom.MathLib.Vector3.NegativeUnitZ;
            sceneNode.AttachObject(widget);

            // Set the target mesh for methods like Font.DrawText
            meshRenderer.BeginRender(widget);
            Rect dummyRect = new Rect();
            dummyRect.left = 0;
            dummyRect.top = 0;
            dummyRect.Height = 150;
            dummyRect.Width = 600;
            font.DrawText("This is a test", dummyRect, 0);
            meshRenderer.EndRender();
        }
 public void NodeRemoved(ObjectNode node)
 {
     if (RightKind(node))
         nodesRemovedSinceLastRebuild++;
 }
 protected bool RightKind(ObjectNode node)
 {
     return (kind == StaticGeometryKind.BigOrLittleNode ||
             (node.PerceptionRadius == 0) == (kind == StaticGeometryKind.LittleNode))
         && (node.Entity == null || node.Entity.Mesh.Skeleton == null);
 }
        protected void input_MouseDown(object sender, Axiom.Input.MouseEventArgs e)
        {
            mouseDownEvent = e;
            mouseDownObject = mouseoverObject;

            if (e.Button != MouseButtons.None)
            {
                // Keep track of which mouse buttons we think are down, and
                // send those to the gui system.
                if (!mouseButtonsDown.Contains(e.Button))
                {
                    mouseButtonsDown.Add(e.Button);
                    log.InfoFormat("Added mouse button {0} to list of down buttons", e.Button);
                    GuiSystem.Instance.OnMouseDown(e);
                }
            }
        }
 // By the time this method is called, we know for sure that
 // the object has collision volumes.
 protected float CheckCollisionWithCollisionShapes(ObjectNode objNode, Ray ray)
 {
     float distance = float.MaxValue;
     if (objNode.Collider != null)
     {
         MovingObject mo = objNode.Collider;
         foreach (MovingPart part in mo.parts)
         {
             CollisionShape partShape = mo.parts[0].shape;
             // Check for intersection of a line 1000 meters long from the ray origin toward the ray direction
             float distanceToShape = partShape.RayIntersectionDistance(ray.Origin, ray.Origin + ray.Direction * (1000f * OneMeter));
             if (distanceToShape == float.MaxValue)
                 continue;
             else if (distanceToShape < distance)
                 distance = distanceToShape;
         }
     }
     else if (objNode.CollisionShapes != null)
     {
         foreach (CollisionShape shape in objNode.CollisionShapes)
         {
             // Check for intersection of a line 1000 meters long from the ray origin toward the ray direction
             float distanceToShape = shape.RayIntersectionDistance(ray.Origin, ray.Origin + ray.Direction * (1000f * OneMeter));
             if (distanceToShape == float.MaxValue)
                 continue;
             else if (distanceToShape < distance)
             {
                 //                         log.DebugFormat("Client.CheckCollisionWithCollisionShapes: objNode {0}, distanceToShape {1}, shape {2}",
                 //                             objNode.Name,distanceToShape, shape);
                 distance = distanceToShape;
             }
         }
     }
     return distance;
 }
 /// <summary>
 ///   Helper method to target mobs.  This is used to handle targetting.
 ///   Typically F8 will invoke this to target nearest mob (last = null)
 ///   Typically Tab will invoke this to target closest mob (or last)
 /// </summary>
 /// <param name="last">last mob targetted</param>
 /// <param name="reverse">whether we are spiraling in instead of out</param>
 /// <param name="onlyAttackable">
 ///   whether we should exclude objects that are not attackable
 /// </param>
 public void TargetMobHelper(ObjectNode last, bool reverse, bool onlyAttackable)
 {
     // Get a copy of the list of mobs
     List<MobNode> mobNodes = new List<MobNode>(worldManager.GetMobNodes());
     mobNodes.Remove(client.Player);
     IComparer<MobNode> comparer = new DistanceComparer(client.Player);
     mobNodes.Sort(comparer);
     if (reverse)
         mobNodes.Reverse();
     // Ideally, I would set lastMob to be the last mob within
     // targetting range, but for now, I'll just consider all.
     bool lastFound = (last == null) ? true : false;
     ObjectNode target = null;
     int lastIndex = -1;
     if (last != null) {
         for (int i = 0; i < mobNodes.Count; ++i)
             if (mobNodes[i] == last) {
                 lastIndex = i;
                 break;
             }
     }
     // Now, starting at lastIndex + 1, loop around the list
     for (int i = 1; i < mobNodes.Count; ++i) {
         int index = (i + lastIndex) % mobNodes.Count;
         if (!onlyAttackable || IsAttackable(mobNodes[index])) {
             target = mobNodes[index];
             break;
         }
     }
     // If we found the 'last' object, and found another object
     if (target != null)
         client.Target = target;
 }
        public void OnTick(object source, long time)
        {
            PointF mousePos = GuiSystem.Instance.MousePosition;

            UiSystem.InjectTick();
            UiSystem.UpdateMouseOver();

            if (!cursorEnabled)
                return;

            // If the mouse is over a UI widget, don't do the mouseover or mouse click
            // events for the world objects.
            if (client.GuiHasFocus)
                return;

            // At some point, I need this cast ray logic to have
            // a concept of only hostile or only friendly or not
            // player or stuff like that.  For now, I just set this
            // up to not include the player object.
            ObjectNode target = client.CastRay(mousePos.X / client.Viewport.ActualWidth,
                                               mousePos.Y / client.Viewport.ActualHeight);

            // MouseExit/MouseEnter events
            if (mouseoverObject != target) {
                if (mouseoverObject != null)
                    mouseoverObject.OnMouseExit(null);
                mouseoverObject = target;
                if (mouseoverObject != null)
                    mouseoverObject.OnMouseEnter(null);
            }
        }
 /// <summary>
 ///   This method is called when we remove an object from the world.
 ///   This method will unregister the mouse events, clear the
 ///   name and bubble widgets, and remove the collision volumes.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="objNode"></param>
 private void OnObjectRemoved(object sender, ObjectNode objNode)
 {
     if (objNode == null)
         return;
     RemoveCollisionObject(objNode);
 }
 /// <summary>
 ///   This method is called when we add an object from the world.
 ///   This method will register the mouse events, set up the
 ///   name and bubble widgets, and add the collision volumes.
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="objNode"></param>
 private void OnObjectAdded(object sender, ObjectNode objNode)
 {
     if (objNode == null)
         return;
     AddCollisionObject(objNode);
     if (objNode is Player) {
         PlayerEnteringWorld();
         return;
     }
 }
 /// <summary>
 ///   Remove the associated collision data from an object.
 /// </summary>
 /// <param name="objNode">the object for which we are removing the collision data</param>
 public void RemoveCollisionObject(ObjectNode objNode)
 {
     if (worldManager.CollisionHelper == null)
         return;
     bool static_object = true;
     if ((objNode.ObjectType == ObjectNodeType.Npc) ||
         (objNode.ObjectType == ObjectNodeType.User)) {
         static_object = false;
     }
     if (static_object) {
         worldManager.CollisionHelper.RemoveCollisionShapesWithHandle(objNode.Oid);
         RegionVolumes.Instance.RemoveCollisionShapesWithHandle(objNode.Oid);
     } else {
         if (objNode.Collider != null)
             objNode.Collider.Dispose();
         objNode.Collider = null;
     }
 }
        /// <summary>
        ///   Add the collision data for an object.  This involves looking 
        ///   for a physics file that matches the mesh file's name, and 
        ///   loading the information from that file to build collision 
        ///   volumes.
        /// </summary>
        /// <param name="objNode">the object for which we are adding the collision data</param>
        public void AddCollisionObject(ObjectNode objNode)
        {
            if (worldManager.CollisionHelper == null)
                return;
            if (!objNode.UseCollisionObject)
                return;
            // Create a set of collision shapes for the object
            List<CollisionShape> shapes = new List<CollisionShape>();
            string meshName = objNode.Entity.Mesh.Name;
            PhysicsData pd = new PhysicsData();
            PhysicsSerializer ps = new PhysicsSerializer();
            bool static_object = true;
            if ((objNode.ObjectType == ObjectNodeType.Npc) ||
                (objNode.ObjectType == ObjectNodeType.User)) {
                static_object = false;
            }

            if (meshName.EndsWith(".mesh")) {
                string physicsName = meshName.Substring(0, meshName.Length - 5) + ".physics";
                try {
                    Stream stream = ResourceManager.FindCommonResourceData(physicsName);
                    ps.ImportPhysics(pd, stream);
                    foreach (SubEntity subEntity in objNode.Entity.SubEntities) {
                        if (subEntity.IsVisible) {
                            string submeshName = subEntity.SubMesh.Name;
                            List<CollisionShape> subEntityShapes = pd.GetCollisionShapes(submeshName);
                            foreach (CollisionShape subShape in subEntityShapes) {
                                // static objects will be transformed here, but movable objects
                                // are transformed on the fly
                                if (static_object)
                                    subShape.Transform(objNode.SceneNode.DerivedScale,
                                                       objNode.SceneNode.DerivedOrientation,
                                                       objNode.SceneNode.DerivedPosition);
                                shapes.Add(subShape);
                                log.DebugFormat("Added collision shape for oid {0}, subShape {1}, subMesh {2}",
                                                objNode.Oid, subShape, submeshName);
                            }
                        }
                    }
                    // Now populate the region volumes
                    foreach (KeyValuePair<string, List<CollisionShape>> entry in pd.CollisionShapes) {
                        string regionName = RegionVolumes.ExtractRegionName(entry.Key);
                        if (regionName != "") {
                            // We must record this region - - must be
                            // a static object
                            Debug.Assert(static_object);
                            List<CollisionShape> subShapes = new List<CollisionShape>();
                            foreach (CollisionShape subShape in entry.Value) {
                                subShape.Transform(objNode.SceneNode.DerivedScale,
                                                   objNode.SceneNode.DerivedOrientation,
                                                   objNode.SceneNode.DerivedPosition);
                                subShapes.Add(subShape);
                            }
                            RegionVolumes.Instance.AddRegionShapes(objNode.Oid, regionName, subShapes);
                        }
                    }
                } catch (Exception) {
                    // Unable to load physics data -- use a sphere or no collision data?
                    log.InfoFormat("Unable to load physics data: {0}", physicsName);
                    //// For now, I'm going to put in spheres.  Later I should do something real.
                    //CollisionShape shape = new CollisionSphere(Vector3.Zero, Client.OneMeter);
                    //if (static_object)
                    //    // static objects will be transformed here, but movable objects
                    //    // are transformed on the fly
                    //    shape.Transform(objNode.SceneNode.DerivedScale,
                    //                    objNode.SceneNode.DerivedOrientation,
                    //                    objNode.SceneNode.DerivedPosition);
                    //shapes.Add(shape);
                }
            }

            if (static_object) {
                foreach (CollisionShape shape in shapes)
                    worldManager.CollisionHelper.AddCollisionShape(shape, objNode.Oid);
                objNode.CollisionShapes = shapes;
            } else {
                MovingObject mo = new MovingObject(worldManager.CollisionHelper);
                foreach (CollisionShape shape in shapes)
                    worldManager.CollisionHelper.AddPartToMovingObject(mo, shape);
                objNode.Collider = mo;
                objNode.Collider.Transform(objNode.SceneNode.DerivedScale,
                                           objNode.SceneNode.DerivedOrientation,
                                           objNode.SceneNode.DerivedPosition);
            }
        }
 /// <summary>
 /// Private function to do the work of ReplaceWorldObject.
 /// </summary>
 /// <param name="movie">
 /// The movie we're going to play on the object.
 /// </param>
 /// <param name="on">
 /// The scene object to replace.
 /// </param>
 /// <returns>
 /// True if the object was replaced, false if it wasn't.
 /// </returns>
 private static bool AttachToNode(IMovie movie, ObjectNode on)
 {
     SceneNode sn = on.SceneNode;
     IEnumerator ie = sn.Objects.GetEnumerator();
     ie.MoveNext();
     MovableObject mo = (MovableObject)ie.Current;
     Entity en = (Entity)mo;
     if (ReplaceEntity(en,
         MeshName(movie),
         MaterialName(movie),
         movie.TextureName(),
         movie.VideoSize(),
         movie.TextureSize()))
     {
         return movie.SetTextureCoordinates(MaterialName(movie));
     }
     else
     {
         return false;
     }
 }