Exemple #1
0
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        ConnectionSetCompiler compiler = context.connCompiler;
        List <Component>      items    = context.components;
        List <byte>           areas    = context.areas;

        int count = 0;

        for (int i = 0; i < items.Count; i++)
        {
            Component item = items[i];

            if (item is OFMConnection)
            {
                OFMConnection conn = (OFMConnection)item;
                byte          area = (conn.OverrideArea ? conn.Area : areas[i]);

                compiler.Add(conn.StartPoint.ToVector3(), conn.EndPoint.ToVector3()
                             , conn.Radius
                             , conn.IsBidirectional
                             , area
                             , conn.Flags
                             , (uint)conn.UserId);

                count++;
            }
        }

        context.Log(string.Format("Compiled off-mesh connections: {0}", count), this);
    }
Exemple #2
0
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.FilterComponents"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.FilterComponents || context == null)
        {
            return(true);
        }

        context.info.filterCount++;

        List <Component> items = context.components;

        int count = 0;

        for (int i = items.Count - 1; i >= 0; i--)
        {
            if (!items[i].gameObject.isStatic)
            {
                items.RemoveAt(i);
                count++;
            }
        }

        context.Log(string.Format("{0}: Applied static filter. Removed {1} components."
                                  , name, count)
                    , this);

        return(true);
    }
Exemple #3
0
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.FilterComponents"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.FilterComponents || context == null)
            return true;

        context.info.filterCount++;

        List<Component> items = context.components;

        int count = 0;

        for (int i = items.Count - 1; i >= 0; i--)
        {
            if (!items[i].gameObject.isStatic)
            {
                items.RemoveAt(i);
                count++;
            }
        }

        context.Log(string.Format("{0}: Applied static filter. Removed {1} components."
            , name, count)
            , this);

        return true;
    }
Exemple #4
0
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.FilterComponents"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.FilterComponents)
        {
            return(true);
        }

        if (meshes == null)
        {
            context.LogError(name + " Mesh exclusion list is null. (Invalid processor state.)"
                             , this);
            return(false);
        }

        if (meshes.Count == 0)
        {
            context.Log(name + ": Filter is inactive. No meshes configured to filter.", this);
            return(true);
        }

        List <Component> targetFilters = context.components;

        int removed = 0;

        for (int iTarget = targetFilters.Count - 1; iTarget >= 0; iTarget--)
        {
            if (!(targetFilters[iTarget] is MeshFilter))
            {
                continue;
            }

            MeshFilter filter = (MeshFilter)targetFilters[iTarget];

            if (!filter)
            {
                continue;
            }

            MatchPredicate p = new MatchPredicate(filter.sharedMesh, matchType, true);

            int iSource = meshes.FindIndex(p.Matches);

            if (iSource != -1)
            {
                targetFilters.RemoveAt(iTarget);
                removed++;
            }
        }

        if (removed > 0)
        {
            context.Log(string.Format("{0}: Filtered out {1} components.", name, removed), this);
        }
        else
        {
            context.Log(name + ": No components filtered.", this);
        }

        return(true);
    }
Exemple #5
0
    private Terrain GetTerrain(InputBuildContext context)
    {
        if (terrainData == null)
        {
            return(null);
        }

        Terrain[] items;

        if (context == null)
        {
            items = (Terrain[])FindObjectsOfType(typeof(Terrain));
        }
        else
        {
            items = context.GetFromScene <Terrain>();
        }

        if (items.Length == 0)
        {
            return(null);
        }

        Terrain selected = null;
        bool    multiple = false;

        foreach (Terrain item in items)
        {
            if (item.terrainData == terrainData)
            {
                if (selected == null)
                {
                    selected = item;
                }
                else
                {
                    multiple = true;
                }
            }
        }

        if (multiple)
        {
            string msg = string.Format(
                "Multiple terrains in the scene use the same data. {0} was selected"
                , selected.name);

            if (context == null)
            {
                Debug.LogWarning(msg, this);
            }
            else
            {
                context.Log(msg, this);
            }
        }

        return(selected);
    }
    private void Load(InputBuildContext context)
    {
        context.info.loaderCount++;

        int count = context.LoadFromScene<NMGenAreaMarker>();

        context.Log(string.Format("Loaded {0} area markers.", count), this);
    }
Exemple #7
0
    private void Load(InputBuildContext context)
    {
        context.info.loaderCount++;

        int count = context.LoadFromScene <OFMConnection>();

        context.Log(string.Format("Loaded {0} off-mesh connections.", count), this);
    }
Exemple #8
0
    private void Load(InputBuildContext context)
    {
        context.info.loaderCount++;

        int count = context.LoadFromScene <MeshFilter>();

        context.Log(string.Format("{0}: Loaded {1} MeshFilters", name, count), this);
    }
    private void Load(InputBuildContext context)
    {
        context.info.loaderCount++;

        int count = context.LoadFromScene <NMGenAreaMarker>();

        context.Log(string.Format("Loaded {0} area markers.", count), this);
    }
    private void Load(InputBuildContext context)
    {
        context.info.loaderCount++;

        int count = context.LoadFromScene<OFMConnection>();

        context.Log(string.Format("Loaded {0} off-mesh connections.", count), this);
    }
Exemple #11
0
        private InputBuilder(InputBuildContext context, IInputBuildProcessor[] processors)
        {
            mContext = context;
            mInputProcessors = processors;

            System.Array.Sort(mInputProcessors, new PriorityComparer<IInputBuildProcessor>(true));

            mState = InputBuildState.LoadComponents;
        }
    private bool ProcessPost(InputBuildContext context)
    {
        if (!ProcessValidation(context))
        {
            return(false);
        }

        context.info.postCount++;

        if (areas.Count == 0)
        {
            context.Log("No area/flag maps.  No action taken.", this);
            return(true);
        }

        ConnectionSetCompiler conns = context.connCompiler;

        bool applied = false;

        for (int i = 0; i < areas.Count; i++)
        {
            byte   area = areas[i];
            ushort flag = (ushort)flags[i];

            int marked = 0;

            for (int iConn = 0; iConn < conns.Count; iConn++)
            {
                OffMeshConnection conn = conns[iConn];

                if (conn.area == area)
                {
                    conn.flags  |= flag;
                    conns[iConn] = conn;
                    marked++;
                }
            }

            if (marked > 0)
            {
                string msg = string.Format(
                    "Added '0x{0:X}' flags to {1} connections with the area {2}."
                    , flag, marked, area);

                context.Log(msg, this);

                applied = true;
            }
        }

        if (!applied)
        {
            context.Log("No flags applied.", this);
        }

        return(true);
    }
 private bool ProcessValidation(InputBuildContext context)
 {
     if (flags == null || areas == null || flags.Count != areas.Count)
     {
         context.Log("Area/Flag size error. (Invalid processor state.)", this);
         return(false);
     }
     return(true);
 }
Exemple #14
0
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        InputGeometryCompiler compiler = context.geomCompiler;
        List <Component>      items    = context.components;
        List <byte>           areas    = context.areas;

        for (int i = 0; i < items.Count; i++)
        {
            Component item = items[i];

            if (item is Terrain)
            {
                Terrain terrain = (Terrain)item;

                if (terrain.terrainData != terrainData)
                {
                    continue;
                }

                TriangleMesh mesh   = TerrainUtil.TriangulateSurface(terrain, mResolution);
                byte[]       lareas = NMGen.CreateAreaBuffer(mesh.triCount, areas[i]);

                if (compiler.AddTriangles(mesh, lareas))
                {
                    string msg = string.Format("Compiled the {0} terrain surface. Triangles: {1}"
                                               , terrain.name, mesh.triCount);

                    context.Log(msg, this);
                }
                else
                {
                    string msg =
                        string.Format("Compiler rejected mesh for the {0} terrain.", terrain.name);

                    context.LogError(msg, this);

                    return;
                }

                if (includeTrees)
                {
                    int before = compiler.TriCount;

                    TerrainUtil.TriangluateTrees(terrain, areas[i], compiler);

                    string msg = string.Format("Compiled the {0} terrain trees. Triangles: {1}"
                                               , terrain.name, compiler.TriCount - before);

                    context.Log(msg, this);
                }

                break;
            }
        }
    }
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.ApplyAreaModifiers"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.ApplyAreaModifiers)
        {
            return(true);
        }

        context.info.areaModifierCount++;

        if (meshes == null || areas == null || meshes.Count != areas.Count)
        {
            context.LogError("Mesh/Area size error. (Invalid processor state.)", this);
            return(false);
        }

        if (meshes.Count == 0)
        {
            context.Log("No action taken. No mesh areas defined.", this);
            return(true);
        }

        List <Component> targetFilters = context.components;
        List <byte>      targetAreas   = context.areas;

        int applied = 0;

        for (int iTarget = 0; iTarget < targetFilters.Count; iTarget++)
        {
            if (!(targetFilters[iTarget] is MeshFilter))
            {
                continue;
            }

            MeshFilter filter = (MeshFilter)targetFilters[iTarget];

            if (filter == null || targetAreas[iTarget] == org.critterai.nmgen.NMGen.NullArea)
            {
                // Never override null area.
                continue;
            }

            MatchPredicate p = new MatchPredicate(filter.sharedMesh, matchType, true);

            int iSource = meshes.FindIndex(p.Matches);

            if (iSource != -1)
            {
                targetAreas[iTarget] = areas[iSource];
                applied++;
            }
        }

        context.Log(string.Format("Applied area(s) to {0} components.", applied), this);

        return(true);
    }
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.CompileInput"/> and
    /// <see cref="InputBuildState.PostProcess"/> states.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state == InputBuildState.CompileInput)
        {
            return(ProcessCompile(context));
        }

        if (state == InputBuildState.PostProcess)
        {
            return(ProcessPost(context));
        }

        return(true);
    }
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.FilterComponents"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.FilterComponents)
            return true;

        if (meshes == null)
        {
            context.LogError(name + " Mesh exclusion list is null. (Invalid processor state.)"
                , this);
            return false;
        }

        if (meshes.Count == 0)
        {
            context.Log(name + ": Filter is inactive. No meshes configured to filter.", this);
            return true;
        }

        List<Component> targetFilters = context.components;

        int removed = 0;
        for (int iTarget = targetFilters.Count - 1; iTarget >= 0; iTarget--)
        {
            if (!(targetFilters[iTarget] is MeshFilter))
                continue;

            MeshFilter filter = (MeshFilter)targetFilters[iTarget];

            if (!filter)
                continue;

            MatchPredicate p = new MatchPredicate(filter.sharedMesh, matchType, true);

            int iSource = meshes.FindIndex(p.Matches);

            if (iSource != -1)
            {
                targetFilters.RemoveAt(iTarget);
                removed++;
            }
        }

        if (removed > 0)
            context.Log(string.Format("{0}: Filtered out {1} components.", name, removed), this);
        else
            context.Log(name + ": No components filtered.", this);

        return true;
    }
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        List <Component> items = context.components;

        int count = 0;

        // The components can't provide the processor directly because processors are editor-only.

        foreach (Component item in items)
        {
            if (item is CylinderAreaMarker)
            {
                CylinderAreaMarker.MarkerData data = ((CylinderAreaMarker)item).GetMarkerData();

                AreaCylinderMarker processor = AreaCylinderMarker.Create(item.name
                                                                         , data.priority
                                                                         , data.area
                                                                         , data.centerBase.ToVector3()
                                                                         , data.radius
                                                                         , data.height);

                context.processors.Add(processor);

                count++;
            }
            else if (item is BoxAreaMarker)
            {
                BoxAreaMarker.MarkerData data = ((BoxAreaMarker)item).GetMarkerData();

                org.critterai.Vector3[] vs = VectorHelper.ToVector3Array(ref data.verts);

                AreaConvexMarker processor = AreaConvexMarker.Create(item.name
                                                                     , data.priority
                                                                     , data.area
                                                                     , vs
                                                                     , data.ymin
                                                                     , data.ymax);

                context.processors.Add(processor);

                count++;
            }
        }

        context.Log(string.Format("Loaded {0} area markers.", count), this);
    }
Exemple #19
0
    private void Load(InputBuildContext context)
    {
        context.info.loaderCount++;

        Terrain item = GetTerrain(context);

        if (!item)
        {
            context.Log(string.Format("No terrain found using {0} terrain data.", terrainData.name)
                        , this);
        }
        else
        {
            context.Load(item);
            context.Log(string.Format("Loaded the {0} terrain object.", terrainData.name), this);
        }
    }
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Processes during the <see cref="InputBuildState.LoadComponents"/>
    /// and <see cref="InputBuildState.CompileInput"/> states.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (context != null)
        {
            switch (state)
            {
            case InputBuildState.CompileInput:

                Compile(context);
                break;

            case InputBuildState.LoadComponents:

                Load(context);
                break;
            }
        }

        return(true);
    }
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Processes during the <see cref="InputBuildState.LoadComponents"/> 
    /// and <see cref="InputBuildState.CompileInput"/> states.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (context != null)
        {
            switch (state)
            {
                case InputBuildState.CompileInput:

                    Compile(context);
                    break;

                case InputBuildState.LoadComponents:

                    Load(context);
                    break;
            }
        }

        return true;
    }
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.ApplyAreaModifiers"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state == InputBuildState.ApplyAreaModifiers)
        {
            context.info.areaModifierCount++;

            List<byte> areas = context.areas;

            for (int i = 0; i < areas.Count; i++)
            {
                areas[i] = mDefaultArea;
            }

            string msg = string.Format("{0}: Applied default area to all components: {1}"
                , name, mDefaultArea);

            context.Log(msg, this);
        }

        return true;
    }
Exemple #23
0
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.ApplyAreaModifiers"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state == InputBuildState.ApplyAreaModifiers)
        {
            context.info.areaModifierCount++;

            List <byte> areas = context.areas;

            for (int i = 0; i < areas.Count; i++)
            {
                areas[i] = mDefaultArea;
            }

            string msg = string.Format("{0}: Applied default area to all components: {1}"
                                       , name, mDefaultArea);

            context.Log(msg, this);
        }

        return(true);
    }
    private bool ProcessCompile(InputBuildContext context)
    {
        if (!ProcessValidation(context))
        {
            return(false);
        }

        context.info.compilerCount++;

        if (areas.Count == 0)
        {
            context.Log("No area/flag maps.  No action taken.", this);
            return(true);
        }

        ushort[] sflags = new ushort[flags.Count];

        for (int i = 0; i < sflags.Length; i++)
        {
            // The editor should prevent overflows.
            sflags[i] = (ushort)flags[i];
        }

        AreaFlagMapper mapper = AreaFlagMapper.Create(name, Priority, areas.ToArray(), sflags);

        if (mapper == null)
        {
            context.LogError("Failed to create NMGen processor. Unexpected invalid data.", this);
            return(false);
        }

        context.processors.Add(mapper);

        context.Log(string.Format("Added {0} NMGen processor.", typeof(AreaFlagMapper).Name), this);

        return(true);
    }
Exemple #25
0
    private void Load(InputBuildContext context)
    {
        context.info.loaderCount++;

        int count = context.LoadFromScene<MeshFilter>();

        context.Log(string.Format("{0}: Loaded {1} MeshFilters", name, count), this);
    }
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.ApplyAreaModifiers"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.ApplyAreaModifiers)
            return true;

        context.info.areaModifierCount++;

        if (tags == null || areas == null || tags.Count != areas.Count)
        {
            context.Log("Mesh/Area size error. (Invalid processor state.)", this);
            return false;
        }

        if (tags.Count == 0)
        {
            context.Log("No action taken. No tags defined.", this);
            return true;
        }

        List<Component> targetItems = context.components;
        List<byte> targetAreas = context.areas;

        int applied = 0;
        for (int iTarget = 0; iTarget < targetItems.Count; iTarget++)
        {
            Component targetItem = targetItems[iTarget];

            if (targetItem == null || targetAreas[iTarget] == NMGen.NullArea)
                // Don't override null area.
                continue;

            int iSource = tags.IndexOf(targetItem.tag);

            if (iSource != -1)
            {
                targetAreas[iTarget] = areas[iSource];
                applied++;
                continue;
            }

            if (recursive)
            {
                // Need to see if the tag is on any parent.
                Transform parent = targetItem.transform.parent;

                while (parent != null)
                {
                    iSource = tags.IndexOf(parent.tag);

                    if (iSource != -1)
                    {
                        // One of the tags is on this item.
                        targetAreas[iTarget] = areas[iSource];
                        applied++;
                        break;
                    }
                    parent = parent.parent;
                }
            }
        }

        context.Log(string.Format("{1}: Applied area(s) to {0} components", applied, name), this);

        return true;
    }
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.CompileInput"/> and
    /// <see cref="InputBuildState.PostProcess"/> states.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state == InputBuildState.CompileInput)
            return ProcessCompile(context);

        if (state == InputBuildState.PostProcess)
            return ProcessPost(context);

        return true;
    }
Exemple #28
0
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        ColliderHelper colliderHelper = (colocationOption == MeshColocationOption.Collider)
            ? new ColliderHelper()
            : null;

        InputGeometryCompiler compiler = context.geomCompiler;

        List<Component> master = new List<Component>(context.components);
        List<byte> areas = new List<byte>(context.areas);

        Queue<MeshFilter> filters = new Queue<MeshFilter>();

        int count = 0;
        int ignored = 0;
        while (master.Count > 0)
        {
            byte area = 0;

            for (int i = master.Count - 1; i >= 0; i--)
            {
                Component item = master[i];

                if (item is MeshFilter)
                {
                    MeshFilter filter = (MeshFilter)item;
                    if (filter.sharedMesh == null)
                    {
                        ignored++;
                        areas.RemoveAt(i);
                        master.RemoveAt(i);
                    }
                    else
                    {
                        if (filters.Count == 0)
                            area = areas[i];

                        if (areas[i] == area)
                        {
                            count++;
                            filters.Enqueue(filter);
                            areas.RemoveAt(i);
                            master.RemoveAt(i);
                        }
                    }
                }
                else
                {
                    areas.RemoveAt(i);
                    master.RemoveAt(i);
                }
            }

            if (filters.Count > 0)
                CombineMeshes(filters, area, compiler, colliderHelper);
        }

        if (colliderHelper != null)
            colliderHelper.Dispose();

        if (ignored > 0)
        {
            string msg = string.Format("{0}: Ignored {1} MeshFilters with a null mesh."
                , name, ignored);

            context.Log(msg, this);
        }

        context.Log(string.Format("{0}: Compiled {1} MeshFilters.", name, count), this);
    }
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        ConnectionSetCompiler compiler = context.connCompiler;
        List<Component> items = context.components;
        List<byte> areas = context.areas;

        int count = 0;

        for (int i = 0; i < items.Count; i++)
        {
            Component item = items[i];

            if (item is OFMConnection)
            {
                OFMConnection conn = (OFMConnection)item;
                byte area = (conn.OverrideArea ? conn.Area : areas[i]);

                compiler.Add(conn.StartPoint, conn.EndPoint
                    , conn.Radius
                    , conn.IsBidirectional
                    , area
                    , conn.Flags
                    , (uint)conn.UserId);

                count++;
            }
        }

        context.Log(string.Format("Compiled off-mesh connections: {0}", count), this);
    }
Exemple #30
0
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.ApplyAreaModifiers"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.ApplyAreaModifiers)
        {
            return(true);
        }

        context.info.areaModifierCount++;

        if (tags == null || areas == null || tags.Count != areas.Count)
        {
            context.Log("Mesh/Area size error. (Invalid processor state.)", this);
            return(false);
        }

        if (tags.Count == 0)
        {
            context.Log("No action taken. No tags defined.", this);
            return(true);
        }

        List <Component> targetItems = context.components;
        List <byte>      targetAreas = context.areas;

        int applied = 0;

        for (int iTarget = 0; iTarget < targetItems.Count; iTarget++)
        {
            Component targetItem = targetItems[iTarget];

            if (targetItem == null || targetAreas[iTarget] == NMGen.NullArea)
            {
                // Don't override null area.
                continue;
            }

            int iSource = tags.IndexOf(targetItem.tag);

            if (iSource != -1)
            {
                targetAreas[iTarget] = areas[iSource];
                applied++;
                continue;
            }

            if (recursive)
            {
                // Need to see if the tag is on any parent.
                Transform parent = targetItem.transform.parent;

                while (parent != null)
                {
                    iSource = tags.IndexOf(parent.tag);

                    if (iSource != -1)
                    {
                        // One of the tags is on this item.
                        targetAreas[iTarget] = areas[iSource];
                        applied++;
                        break;
                    }
                    parent = parent.parent;
                }
            }
        }

        context.Log(string.Format("{1}: Applied area(s) to {0} components", applied, name), this);

        return(true);
    }
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        List<Component> items = context.components;

        int count = 0;

        // The components can't provide the processor directly because processors are editor-only.

        foreach (Component item in items)
        {
            if (item is CylinderAreaMarker)
            {
                CylinderAreaMarker.MarkerData data = ((CylinderAreaMarker)item).GetMarkerData();

                AreaCylinderMarker processor = AreaCylinderMarker.Create(item.name
                    , data.priority
                    , data.area
                    , data.centerBase
                    , data.radius
                    , data.height);

                context.processors.Add(processor);

                count++;
            }
            else if (item is BoxAreaMarker)
            {
                BoxAreaMarker.MarkerData data = ((BoxAreaMarker)item).GetMarkerData();

                AreaConvexMarker processor = AreaConvexMarker.Create(item.name
                    , data.priority
                    , data.area
                    , data.verts
                    , data.ymin
                    , data.ymax);

                context.processors.Add(processor);

                count++;
            }
        }

        context.Log(string.Format("Loaded {0} area markers.", count), this);
    }
Exemple #32
0
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        InputGeometryCompiler compiler = context.geomCompiler;
        List<Component> items = context.components;
        List<byte> areas = context.areas;

        for (int i = 0; i < items.Count; i++)
        {
            Component item = items[i];

            if (item is Terrain)
            {
                Terrain terrain = (Terrain)item;

                if (terrain.terrainData != terrainData)
                    continue;

                TriangleMesh mesh = TerrainUtil.TriangulateSurface(terrain, mResolution);
                byte[] lareas = NMGen.CreateAreaBuffer(mesh.triCount, areas[i]);

                if (compiler.AddTriangles(mesh, lareas))
                {
                    string msg = string.Format("Compiled the {0} terrain surface. Triangles: {1}"
                        , terrain.name, mesh.triCount);

                    context.Log(msg, this);
                }
                else
                {
                    string msg = 
                        string.Format("Compiler rejected mesh for the {0} terrain.", terrain.name);

                    context.LogError(msg, this);

                    return;
                }

                if (includeTrees)
                {
                    int before = compiler.TriCount;

                    TerrainUtil.TriangluateTrees(terrain, areas[i], compiler);

                    string msg = string.Format("Compiled the {0} terrain trees. Triangles: {1}"
                        , terrain.name, compiler.TriCount - before);

                    context.Log(msg, this);
                }

                break;
            }
        }
    }
Exemple #33
0
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.FilterComponents"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.FilterComponents)
        {
            return(true);
        }

        context.info.filterCount++;

        if (tags == null)
        {
            context.Log(name + " Mesh exclusion list is null. (Invalid processor state.)", this);
            return(false);
        }

        if (tags.Count == 0)
        {
            context.Log(name + ": Filter is inactive. No tags configured to filter.", this);
            return(true);
        }

        List <Component> targetItems = context.components;

        int removed = 0;

        for (int iTarget = targetItems.Count - 1; iTarget >= 0; iTarget--)
        {
            Component targetItem = targetItems[iTarget];

            if (!targetItem)
            {
                continue;
            }

            int iSource = tags.IndexOf(targetItem.tag);

            if (iSource != -1)
            {
                // One of the tags is on this item.
                targetItems.RemoveAt(iTarget);
                removed++;
                continue;
            }

            if (recursive)
            {
                // Need to see if the tag is on any parent.
                Transform parent = targetItem.transform.parent;

                while (parent != null)
                {
                    iSource = tags.IndexOf(parent.tag);

                    if (iSource != -1)
                    {
                        // One of the tags is on this item.
                        targetItems.RemoveAt(iTarget);
                        removed++;
                        break;
                    }
                    parent = parent.parent;
                }
            }
        }

        if (removed > 0)
        {
            context.Log(string.Format("{0}: Filtered out {1} components.", name, removed), this);
        }
        else
        {
            context.Log(name + ": No components filtered.", this);
        }

        return(true);
    }
Exemple #34
0
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.FilterComponents"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.FilterComponents)
            return true;

        context.info.filterCount++;

        if (tags == null)
        {
            context.Log(name + " Mesh exclusion list is null. (Invalid processor state.)", this);
            return false;
        }

        if (tags.Count == 0)
        {
            context.Log(name + ": Filter is inactive. No tags configured to filter.", this);
            return true;
        }

        List<Component> targetItems = context.components;

        int removed = 0;
        for (int iTarget = targetItems.Count - 1; iTarget >= 0; iTarget--)
        {
            Component targetItem = targetItems[iTarget];

            if (!targetItem)
                continue;

            int iSource = tags.IndexOf(targetItem.tag);

            if (iSource != -1)
            {
                // One of the tags is on this item.
                targetItems.RemoveAt(iTarget);
                removed++;
                continue;
            }

            if (recursive)
            {
                // Need to see if the tag is on any parent.
                Transform parent = targetItem.transform.parent;

                while (parent != null)
                {
                    iSource = tags.IndexOf(parent.tag);

                    if (iSource != -1)
                    {
                        // One of the tags is on this item.
                        targetItems.RemoveAt(iTarget);
                        removed++;
                        break;
                    }
                    parent = parent.parent;
                }
            }
        }

        if (removed > 0)
            context.Log(string.Format("{0}: Filtered out {1} components.", name, removed), this);
        else
            context.Log(name + ": No components filtered.", this);

        return true;
    }
 private bool ProcessValidation(InputBuildContext context)
 {
     if (flags == null || areas == null || flags.Count != areas.Count)
     {
         context.Log("Area/Flag size error. (Invalid processor state.)", this);
         return false;
     }
     return true;
 }
Exemple #36
0
    private Terrain GetTerrain(InputBuildContext context)
    {
        if (terrainData == null)
            return null;

        Terrain[] items;

        if (context == null)
            items = (Terrain[])FindObjectsOfType(typeof(Terrain));
        else
            items = context.GetFromScene<Terrain>();

        if (items.Length == 0)
            return null;

        Terrain selected = null;
        bool multiple = false;

        foreach (Terrain item in items)
        {
            if (item.terrainData == terrainData)
            {
                if (selected == null)
                    selected = item;
                else
                    multiple = true;
            }
        }

        if (multiple)
        {
            string msg = string.Format(
                "Multiple terrains in the scene use the same data. {0} was selected"
                , selected.name);

            if (context == null)
                Debug.LogWarning(msg, this);
            else
                context.Log(msg, this);
        }

        return selected;
    }
    private bool ProcessPost(InputBuildContext context)
    {
        if (!ProcessValidation(context))
            return false;

        context.info.postCount++;

        if (areas.Count == 0)
        {
            context.Log("No area/flag maps.  No action taken.", this);
            return true;
        }

        ConnectionSetCompiler conns = context.connCompiler;

        bool applied = false;

        for (int i = 0; i < areas.Count; i++)
        {
            byte area = areas[i];
            ushort flag = (ushort)flags[i];

            int marked = 0;

            for (int iConn = 0; iConn < conns.Count; iConn++)
            {
                OffMeshConnection conn = conns[iConn];

                if (conn.area == area)
                {
                    conn.flags |= flag;
                    conns[iConn] = conn;
                    marked++;
                }
            }

            if (marked > 0)
            {
                string msg = string.Format(
                    "Added '0x{0:X}' flags to {1} connections with the area {2}."
                   , flag, marked, area);

                context.Log(msg, this);

                applied = true;
            }
        }

        if (!applied)
            context.Log("No flags applied.", this);

        return true;
    }
Exemple #38
0
    private void Load(InputBuildContext context)
    {
        context.info.loaderCount++;
        
        Terrain item = GetTerrain(context);

        if (!item)
        {
            context.Log(string.Format("No terrain found using {0} terrain data.", terrainData.name)
                , this);
        }
        else
        {
            context.Load(item);
            context.Log(string.Format("Loaded the {0} terrain object.", terrainData.name), this);
        }
    }
    private bool ProcessCompile(InputBuildContext context)
    {
        if (!ProcessValidation(context))
            return false;

        context.info.compilerCount++;

        if (areas.Count == 0)
        {
            context.Log("No area/flag maps.  No action taken.", this);
            return true;
        }

        ushort[] sflags = new ushort[flags.Count];

        for (int i = 0; i < sflags.Length; i++)
        {
            // The editor should prevent overflows.
            sflags[i] = (ushort)flags[i];
        }

        AreaFlagMapper mapper = AreaFlagMapper.Create(name, Priority, areas.ToArray(), sflags);

        if (mapper == null)
        {
            context.LogError("Failed to create NMGen processor. Unexpected invalid data.", this);
            return false;
        }

        context.processors.Add(mapper);

        context.Log(string.Format("Added {0} NMGen processor.", typeof(AreaFlagMapper).Name), this);

        return true;
    }
Exemple #40
0
    private void Compile(InputBuildContext context)
    {
        context.info.compilerCount++;

        ColliderHelper colliderHelper = (colocationOption == MeshColocationOption.Collider)
            ? new ColliderHelper()
            : null;

        InputGeometryCompiler compiler = context.geomCompiler;

        List <Component> master = new List <Component>(context.components);
        List <byte>      areas  = new List <byte>(context.areas);

        Queue <MeshFilter> filters = new Queue <MeshFilter>();

        int count   = 0;
        int ignored = 0;

        while (master.Count > 0)
        {
            byte area = 0;

            for (int i = master.Count - 1; i >= 0; i--)
            {
                Component item = master[i];

                if (item is MeshFilter)
                {
                    MeshFilter filter = (MeshFilter)item;
                    if (filter.sharedMesh == null)
                    {
                        ignored++;
                        areas.RemoveAt(i);
                        master.RemoveAt(i);
                    }
                    else
                    {
                        if (filters.Count == 0)
                        {
                            area = areas[i];
                        }

                        if (areas[i] == area)
                        {
                            count++;
                            filters.Enqueue(filter);
                            areas.RemoveAt(i);
                            master.RemoveAt(i);
                        }
                    }
                }
                else
                {
                    areas.RemoveAt(i);
                    master.RemoveAt(i);
                }
            }

            if (filters.Count > 0)
            {
                CombineMeshes(filters, area, compiler, colliderHelper);
            }
        }

        if (colliderHelper != null)
        {
            colliderHelper.Dispose();
        }

        if (ignored > 0)
        {
            string msg = string.Format("{0}: Ignored {1} MeshFilters with a null mesh."
                                       , name, ignored);

            context.Log(msg, this);
        }

        context.Log(string.Format("{0}: Compiled {1} MeshFilters.", name, count), this);
    }
Exemple #41
0
        public static InputBuilder Create(ISceneQuery filter
            , IInputBuildProcessor[] processors
            , InputBuildOption options)
        {
            IInputBuildProcessor[] lprocessors = ArrayUtil.Compress(processors);

            if (lprocessors == null || lprocessors.Length == 0)
                return null;

            for (int i = lprocessors.Length - 1; i >= 0; i--)
            {
                IInputBuildProcessor processor = lprocessors[i];

                if (processor.DuplicatesAllowed)
                    continue;

                System.Type ta = processor.GetType();

                for (int j = i - 1; j >= 0; j--)
                {
                    System.Type tb = lprocessors[j].GetType();

                    if (ta.IsAssignableFrom(tb) || tb.IsAssignableFrom(ta))
                        return null;
                }
            }

            if (lprocessors == processors)
                lprocessors = (IInputBuildProcessor[])lprocessors.Clone();

            InputBuildContext context = new InputBuildContext(filter, options);

            return new InputBuilder(context, lprocessors);
        }
Exemple #42
0
    /// <summary>
    /// Processes the context.
    /// </summary>
    /// <remarks>
    /// <para>
    /// Applied during the <see cref="InputBuildState.ApplyAreaModifiers"/> state.
    /// </para>
    /// </remarks>
    /// <param name="state">The current state of the input build.</param>
    /// <param name="context">The input context to process.</param>
    /// <returns>False if the input build should abort.</returns>
    public bool ProcessInput(InputBuildContext context, InputBuildState state)
    {
        if (state != InputBuildState.ApplyAreaModifiers)
            return true;

        context.info.areaModifierCount++;

        if (meshes == null || areas == null || meshes.Count != areas.Count)
        {
            context.LogError("Mesh/Area size error. (Invalid processor state.)", this);
            return false;
        }

        if (meshes.Count == 0)
        {
            context.Log("No action taken. No mesh areas defined.", this);
            return true;
        }

        List<Component> targetFilters = context.components;
        List<byte> targetAreas = context.areas;

        int applied = 0;
        for (int iTarget = 0; iTarget < targetFilters.Count; iTarget++)
        {
            if (!(targetFilters[iTarget] is MeshFilter))
                continue;

            MeshFilter filter = (MeshFilter)targetFilters[iTarget];

            if (filter == null || targetAreas[iTarget] == org.critterai.nmgen.NMGen.NullArea)
                // Never override null area.
                continue;

            MatchPredicate p = new MatchPredicate(filter.sharedMesh, matchType, true);

            int iSource = meshes.FindIndex(p.Matches);

            if (iSource != -1)
            {
                targetAreas[iTarget] = areas[iSource];
                applied++;
            }
        }

        context.Log(string.Format("Applied area(s) to {0} components.", applied), this);

        return true;
    }