コード例 #1
0
ファイル: WmoBatchRender.cs プロジェクト: veserine/Neo
        public bool Intersect(IntersectionParams parameters, ref Ray globalRay, out float distance, out WmoInstance instance)
        {
            distance = float.MaxValue;
            instance = null;

            if (mInstances == null)
            {
                return(false);
            }

            lock (mInstances)
            {
                foreach (var inst in mInstances.Values)
                {
                    float dist;
                    if (inst.Intersects(parameters, ref globalRay, out dist) && dist < distance)
                    {
                        distance = dist;
                        instance = inst;
                    }
                }
            }

            return(instance != null);
        }
コード例 #2
0
ファイル: TexturingViewModel.cs プロジェクト: veserine/Neo
        private void OnWorldClick(IntersectionParams intersectionParams, MouseEventArgs args)
        {
            if (args.Button != MouseButtons.Left)
            {
                return;
            }

            var keys = new byte[256];

            UnsafeNativeMethods.GetKeyboardState(keys);
            if (KeyHelper.IsKeyDown(keys, Keys.ControlKey) || KeyHelper.IsKeyDown(keys, Keys.ShiftKey))
            {
                return;
            }

            if (intersectionParams.ChunkHit == null)
            {
                mLastArea = null;
                return;
            }

            MapArea area;

            if (intersectionParams.ChunkHit.Parent.TryGetTarget(out area) == false)
            {
                return;
            }

            var updateArea = true;

            if (mLastArea != null)
            {
                MapArea lastArea;
                if (mLastArea.TryGetTarget(out lastArea) && lastArea == area)
                {
                    updateArea = false;
                }
            }

            mLastArea = intersectionParams.ChunkHit.Parent;
            if (updateArea)
            {
                SetSelectedTileTextures(mWidget.SelectedTileWrapPanel, area.TextureNames);
            }

            MapChunk lastChunk;

            if (mLastChunk != null && mLastChunk.TryGetTarget(out lastChunk))
            {
                if (lastChunk == intersectionParams.ChunkHit)
                {
                    return;
                }
            }

            mLastChunk = new WeakReference <MapChunk>(intersectionParams.ChunkHit);
            SetSelectedTileTextures(mWidget.SelectedChunkWrapPanel, intersectionParams.ChunkHit.TextureNames);
        }
コード例 #3
0
ファイル: M2RenderInstance.cs プロジェクト: veserine/Neo
        public bool Intersects(IntersectionParams parameters, ref Ray globalRay, out float value)
        {
            value = float.MaxValue;

            if (globalRay.Intersects(ref mBoundingBox) == false)
            {
                return(false);
            }

            var instRay = Picking.Build(ref parameters.ScreenPosition, ref parameters.InverseView,
                                        ref parameters.InverseProjection, ref mInverseMatrix);

            return(mModel.Intersect(ref instRay, out value));
        }
コード例 #4
0
ファイル: ModelSpawnManager.cs プロジェクト: veserine/Neo
        public void OnTerrainClicked(IntersectionParams parameters, MouseEventArgs args)
        {
            if (EditManager.Instance.CurrentMode == EditMode.Chunk)
            {
                return;
            }

            if (args.Button != MouseButtons.Left)
            {
                if (args.Button == MouseButtons.Right)
                {
                    var state = new byte[256];
                    UnsafeNativeMethods.GetKeyboardState(state);
                    if (KeyHelper.IsKeyDown(state, Keys.ControlKey))
                    {
                        WorldFrame.Instance.M2Manager.RemoveInstance(mSelectedModel, M2InstanceUuid);
                        mHoveredInstance = null;
                        mSelectedModel   = null;
                        WorldFrame.Instance.OnWorldClicked -= OnTerrainClicked;
                    }
                }

                ModelEditManager.Instance.IsCopying = false;
                return;
            }

            if (parameters.TerrainHit == false)
            {
                return;
            }

            if (mHoveredInstance == null)
            {
                return;
            }

            SpawnModel(parameters.TerrainPosition);

            ModelEditManager.Instance.IsCopying = !EditorWindowController.Instance.SpawnModel.DeselectModelOnClick;

            if (!ModelEditManager.Instance.IsCopying)
            {
                WorldFrame.Instance.M2Manager.RemoveInstance(mSelectedModel, M2InstanceUuid);
                mHoveredInstance = null;
                mSelectedModel   = null;
                WorldFrame.Instance.OnWorldClicked -= OnTerrainClicked;
            }
        }
コード例 #5
0
        public void Intersect(IntersectionParams parameters)
        {
            var ray = Picking.Build(ref parameters.ScreenPosition,
                                    ref parameters.InverseView, ref parameters.InverseProjection);

            var      hasHit   = false;
            var      minDist  = float.MaxValue;
            MapChunk chunkHit = null;

            // ReSharper disable once InconsistentlySynchronizedField
            foreach (var pair in mAreas)
            {
                MapChunk chunk;
                float    distance;
                if (!pair.Value.AreaFile.Intersect(ref ray, out chunk, out distance))
                {
                    continue;
                }

                hasHit = true;
                if ((distance >= minDist))
                {
                    continue;
                }

                minDist  = distance;
                chunkHit = chunk;
            }

            parameters.TerrainHit = hasHit;
            if (hasHit)
            {
                parameters.TerrainPosition = ray.Position + minDist * ray.Direction;
                parameters.TerrainDistance = minDist;
            }
            else
            {
                parameters.TerrainPosition = new Vector3(float.MaxValue);
            }

            parameters.ChunkHit = chunkHit;
        }
コード例 #6
0
ファイル: MapChunk.cs プロジェクト: veserine/Neo
        public override void SetHole(IntersectionParams intersection, bool add)
        {
            float holesize  = CHUNKSIZE / 4.0f;
            var   min       = BoundingBox.Minimum;
            var   intersect = new Vector2(intersection.TerrainPosition.X, intersection.TerrainPosition.Y);

            for (int x = 0; x < 4; x++)
            {
                for (int y = 0; y < 4; y++)
                {
                    RectangleF bounds = new RectangleF
                                        (
                        min.X + (x * holesize),
                        min.Y + (y * holesize),
                        holesize,
                        holesize
                                        );

                    if (bounds.Contains(intersect))
                    {
                        var baseIndex = y * 2 * 8 + x * 2;
                        int bit       = (1 << (y * 4 + x));

                        if (add)
                        {
                            mHeader.Holes |= bit;
                        }
                        else
                        {
                            mHeader.Holes &= ~bit;
                        }

                        HoleValues[baseIndex]                 =
                            HoleValues[baseIndex + 1]         =
                                HoleValues[baseIndex + 8]     =
                                    HoleValues[baseIndex + 9] = (byte)(add ? 0x00 : 0xFF);
                        return;
                    }
                }
            }
        }
コード例 #7
0
ファイル: WmoManager.cs プロジェクト: veserine/Neo
        public void Intersect(IntersectionParams parameters)
        {
            if (mRenderer == null)
            {
                return;
            }

            var globalRay = Picking.Build(ref parameters.ScreenPosition, ref parameters.InverseView,
                                          ref parameters.InverseProjection);

            var         minDistance = float.MaxValue;
            WmoInstance wmoHit      = null;

            lock (mRenderer)
            {
                foreach (var renderer in mRenderer)
                {
                    WmoInstance hit;
                    float       distance;
                    if (renderer.Value.Intersect(parameters, ref globalRay, out distance, out hit) &&
                        distance < minDistance)
                    {
                        minDistance = distance;
                        wmoHit      = hit;
                    }
                }
            }

            if (wmoHit != null)
            {
                parameters.WmoHit      = true;
                parameters.WmoInstance = wmoHit;
                parameters.WmoModel    = wmoHit.ModelRoot;
                parameters.WmoPosition = globalRay.Position + minDistance * globalRay.Direction;
                parameters.WmoDistance = minDistance;
            }
            else
            {
                parameters.WmoHit = false;
            }
        }
コード例 #8
0
        public bool Intersects(IntersectionParams parameters, ref Ray globalRay, out float distance)
        {
            distance = float.MaxValue;
            if (globalRay.Intersects(ref BoundingBox) == false)
            {
                return(false);
            }

            WmoRootRender renderer;

            if (mRenderer.TryGetTarget(out renderer) == false)
            {
                return(false);
            }

            var instRay = Picking.Build(ref parameters.ScreenPosition, ref parameters.InverseView,
                                        ref parameters.InverseProjection, ref mInverseInstanceMatrix);

            var hasHit = false;

            for (var i = 0; i < GroupBoxes.Length; ++i)
            {
                if (globalRay.Intersects(ref GroupBoxes[i]) == false)
                {
                    continue;
                }

                float dist;
                if (renderer.Groups[i].Intersects(parameters, ref instRay, out dist) && dist < distance)
                {
                    distance = dist;
                    hasHit   = true;
                }
            }

            return(hasHit);
        }
コード例 #9
0
        public override void SetHole(IntersectionParams intersection, bool add)
        {
            float holesize  = CHUNKSIZE / 4.0f;
            var   min       = BoundingBox.Minimum;
            var   intersect = new Vector2(intersection.TerrainPosition.X, intersection.TerrainPosition.Y);

            bool use64bit = (mHeader.Flags & 0x10000) == 0x10000;

            if (!use64bit)
            {
                for (int x = 0; x < 4; x++)
                {
                    for (int y = 0; y < 4; y++)
                    {
                        RectangleF bounds = new RectangleF
                                            (
                            min.X + (x * holesize),
                            min.Y + (y * holesize),
                            holesize,
                            holesize
                                            );

                        if (bounds.Contains(intersect))
                        {
                            y = 3 - y; //Inverse
                            var baseIndex = y * 2 * 8 + x * 2;
                            int bit       = (1 << (y * 4 + x));

                            if (add)
                            {
                                mHeader.Holes |= bit;
                            }
                            else
                            {
                                mHeader.Holes &= ~bit;
                            }

                            HoleValues[baseIndex]                 =
                                HoleValues[baseIndex + 1]         =
                                    HoleValues[baseIndex + 8]     =
                                        HoleValues[baseIndex + 9] = (byte)(add ? 0x00 : 0xFF);
                            return;
                        }
                    }
                }
            }
            else
            {
                holesize = CHUNKSIZE / 8.0f;
                var holeBytes = new byte[8];
                Buffer.BlockCopy(BitConverter.GetBytes(mHeader.Mcvt), 0, holeBytes, 0, 4);
                Buffer.BlockCopy(BitConverter.GetBytes(mHeader.Mcnr), 0, holeBytes, 4, 4);

                for (var x = 0; x < 8; ++x)
                {
                    for (var y = 0; y < 8; ++y)
                    {
                        RectangleF bounds = new RectangleF
                                            (
                            min.X + (x * holesize),
                            min.Y + (y * holesize),
                            holesize,
                            holesize
                                            );

                        if (bounds.Contains(intersect))
                        {
                            y = (7 - y); //Inverse
                            byte bit = (byte)(1 << x);

                            if (add)
                            {
                                holeBytes[y] |= bit;
                            }
                            else
                            {
                                holeBytes[y] = (byte)(holeBytes[y] & ~bit);
                            }

                            mHeader.Mcvt = BitConverter.ToInt32(holeBytes, 0);
                            mHeader.Mcnr = BitConverter.ToInt32(holeBytes, 4);

                            int h = y * 8 + x;
                            HoleValues[h] = (byte)(add ? 0x00 : 0xFF);
                            return;
                        }
                    }
                }
            }
        }
コード例 #10
0
ファイル: ChunkEditManager.cs プロジェクト: veserine/Neo
        private void OnChunkClicked(IntersectionParams intersection, MouseEventArgs e)
        {
            var chunk    = mHoveredChunk;
            var keyState = new byte[256];

            UnsafeNativeMethods.GetKeyboardState(keyState);
            MapArea parent;

            switch (ChunkEditMode)
            {
            case ChunkEditMode.AreaPaint:
                if (SelectedAreaId == 0 || !KeyHelper.IsKeyDown(keyState, Keys.LButton))
                {
                    return;
                }

                if (chunk.Parent.TryGetTarget(out parent))
                {
                    chunk.AreaId = SelectedAreaId;
                    parent.SetChanged();
                    ForceRenderUpdate?.Invoke(chunk, false);
                }
                break;

            case ChunkEditMode.AreaSelect:

                if (!KeyHelper.IsKeyDown(keyState, Keys.LButton))
                {
                    return;
                }

                SelectedAreaId = chunk.AreaId;
                SelectedAreaIdChange?.Invoke(SelectedAreaId);
                break;

            case ChunkEditMode.Hole:

                if (!KeyHelper.IsKeyDown(keyState, Keys.LButton))
                {
                    return;
                }

                if (chunk.Parent.TryGetTarget(out parent))
                {
                    if (SmallHole)
                    {
                        chunk.SetHole(intersection, AddHole);
                    }
                    else
                    {
                        chunk.SetHoleBig(AddHole);
                    }

                    parent.SetChanged();
                    ForceRenderUpdate?.Invoke(chunk, true);
                }

                break;

            case ChunkEditMode.Flags:

                if (!KeyHelper.IsKeyDown(keyState, Keys.LButton))
                {
                    return;
                }

                if (chunk.Parent.TryGetTarget(out parent))
                {
                    if (chunk.HasImpassFlag)
                    {
                        chunk.Flags &= ~0x2u;
                    }
                    else
                    {
                        chunk.Flags |= 0x2;
                    }

                    parent.SetChanged();
                    ForceRenderUpdate?.Invoke(chunk, false);
                }
                break;
            }
        }
コード例 #11
0
ファイル: MapChunk.cs プロジェクト: veserine/Neo
 public abstract void SetHole(IntersectionParams intersection, bool add);
コード例 #12
0
ファイル: M2Manager.cs プロジェクト: veserine/Neo
        public void Intersect(IntersectionParams parameters)
        {
            if (mVisibleInstances == null || mNonBatchedInstances == null || mSortedInstances == null)
            {
                return;
            }

            var globalRay = Picking.Build(ref parameters.ScreenPosition, ref parameters.InverseView,
                                          ref parameters.InverseProjection);

            var minDistance = float.MaxValue;
            M2RenderInstance selectedInstance = null;

            lock (mVisibleInstances)
            {
                foreach (var pair in mVisibleInstances)
                {
                    if (pair.Value.Uuid == Editing.ModelSpawnManager.M2InstanceUuid)
                    {
                        continue;
                    }

                    float dist;
                    if (pair.Value.Intersects(parameters, ref globalRay, out dist) && dist < minDistance)
                    {
                        minDistance      = dist;
                        selectedInstance = pair.Value;
                    }
                }
            }

            lock (mNonBatchedInstances)
            {
                foreach (var pair in mNonBatchedInstances)
                {
                    float dist;
                    if (pair.Value.Intersects(parameters, ref globalRay, out dist) && dist < minDistance)
                    {
                        minDistance      = dist;
                        selectedInstance = pair.Value;
                    }
                }
            }

            lock (mSortedInstances)
            {
                foreach (var pair in mSortedInstances)
                {
                    float dist;
                    if (pair.Value.Intersects(parameters, ref globalRay, out dist) && dist < minDistance)
                    {
                        minDistance      = dist;
                        selectedInstance = pair.Value;
                    }
                }
            }

            if (selectedInstance != null)
            {
                parameters.M2Instance = selectedInstance;
                parameters.M2Model    = selectedInstance.Model;
                parameters.M2Position = globalRay.Position + minDistance * globalRay.Direction;
                parameters.M2Distance = minDistance;
            }

            parameters.M2Hit = selectedInstance != null;
        }
コード例 #13
0
        public bool Intersects(IntersectionParams parameters, ref Ray ray, out float distance)
        {
            distance = float.MaxValue;
            var hasHit = false;

            var     orig = ray.Position;
            var     dir = ray.Direction;
            Vector3 e1, e2, p, T, q;

            foreach (var batch in mBatches)
            {
                for (int i = batch.Batch.StartIndex, j = 0; j < batch.Batch.NumIndices; i += 3, j += 3)
                {
                    var i0 = Data.Indices[i];
                    var i1 = Data.Indices[i + 1];
                    var i2 = Data.Indices[i + 2];
                    Vector3.Subtract(ref Data.Vertices[i1].Position, ref Data.Vertices[i0].Position, out e1);
                    Vector3.Subtract(ref Data.Vertices[i2].Position, ref Data.Vertices[i0].Position, out e2);

                    Vector3.Cross(ref dir, ref e2, out p);
                    float det;
                    Vector3.Dot(ref e1, ref p, out det);

                    if (Math.Abs(det) < 1e-4)
                    {
                        continue;
                    }

                    var invDet = 1.0f / det;
                    Vector3.Subtract(ref orig, ref Data.Vertices[i0].Position, out T);
                    float u;
                    Vector3.Dot(ref T, ref p, out u);
                    u *= invDet;

                    if (u < 0 || u > 1)
                    {
                        continue;
                    }

                    Vector3.Cross(ref T, ref e1, out q);
                    float v;
                    Vector3.Dot(ref dir, ref q, out v);
                    v *= invDet;
                    if (v < 0 || (u + v) > 1)
                    {
                        continue;
                    }

                    float t;
                    Vector3.Dot(ref e2, ref q, out t);
                    t *= invDet;

                    if (t < 1e-4)
                    {
                        continue;
                    }

                    hasHit = true;
                    if (t < distance)
                    {
                        distance = t;
                    }
                }
            }

            return(hasHit);
        }
コード例 #14
0
ファイル: MapManager.cs プロジェクト: Linrasis/WoWEditor
        public void Intersect(IntersectionParams parameters)
        {
            var ray = Picking.Build(ref parameters.ScreenPosition, ref parameters.InverseView,
                ref parameters.InverseProjection);

            var hasHit = false;
            var minDist = float.MaxValue;
            MapChunk chunkHit = null;

            // ReSharper disable once InconsistentlySynchronizedField
            foreach(var pair in mAreas)
            {
                MapChunk chunk;
                float distance;
                if (!pair.Value.AreaFile.Intersect(ref ray, out chunk, out distance)) continue;

                hasHit = true;
                if ((distance >= minDist)) continue;

                minDist = distance;
                chunkHit = chunk;
            }

            parameters.TerrainHit = hasHit;
            if (hasHit)
                parameters.TerrainPosition = ray.Position + minDist * ray.Direction;
            else
                parameters.TerrainPosition = new Vector3(float.MaxValue);

            parameters.ChunkHit = chunkHit;
        }