Exemple #1
0
    private void createLodSys(MeshInstance _mesh)
    {
        if (_mesh != null)
        {
            GD.Print("Create mesh");

            if (_mesh.GetChildCount() > 0)
            {
                GD.Print("Mesh needs to be clear. Remove childs at first");
                return;
            }

            var q2 = (float)(editDock.GetNode("lod2_quality") as Slider).Value;
            var q3 = (float)(editDock.GetNode("lod3_quality") as Slider).Value;

            var lod2Mesh = MeshDecimator.MeshDecimatorTool.generateMesh(q2, _mesh);
            var lod3Mesh = MeshDecimator.MeshDecimatorTool.generateMesh(q3, _mesh);

            //set scale to all other meshinstances
            var tf = (MeshLod)GD.Load <PackedScene>("res://addons/mesh_lod/MeshLod.tscn").Instance();
            _mesh.GetParent().AddChild(tf);
            tf.Translation = _mesh.Translation;
            tf.Rotation    = _mesh.Rotation;
            tf.Scale       = _mesh.Scale;
            tf.lod2Quality = q2;
            tf.lod3Quality = q3;
            tf.Owner       = GetEditorInterface().GetEditedSceneRoot();
            _mesh.GetParent().RemoveChild(_mesh);
            tf.AddChild(_mesh);

            _mesh.Owner = GetEditorInterface().GetEditedSceneRoot();
            tf.Name     = _mesh.Name;
            _mesh.Name  = "lod1";

            _mesh.Translation = Vector3.Zero;
            _mesh.Rotation    = Vector3.Zero;
            _mesh.Scale       = new Vector3(1, 1, 1);

            var lod2 = createLodMesh(_mesh, lod2Mesh);
            lod2.Name = "lod2";

            var lod3 = createLodMesh(_mesh, lod3Mesh);
            lod3.Name = "lod3";

            tf.AddChild(lod2);
            tf.AddChild(lod3);

            lod2.Owner = GetEditorInterface().GetEditedSceneRoot();
            lod3.Owner = GetEditorInterface().GetEditedSceneRoot();

            tf.doLoding();
        }
    }
        void CreateGround(MeshInstance meshInstance, float x, int index)
        {
            float height1 = _mTerrain.GetHeight(x);
            float height2 = _mTerrain.GetHeight(x + WIDTH);

            // test slope
            meshInstance._mVerts.Add(new Vector3(x, BOTTOM, 0));
            meshInstance._mVerts.Add(new Vector3(x + WIDTH, BOTTOM, 0));
            meshInstance._mVerts.Add(new Vector3(x + WIDTH, height2, 0));
            meshInstance._mVerts.Add(new Vector3(x, height1, 0));

            CreateFaces(meshInstance, index, false);
        }
Exemple #3
0
    public void CreateChunk(int x, int y, int z)
    {
        MeshInstance newChunk = new MeshInstance();
        var          id       = newChunk.GetInstanceId();

        newChunk.SetScript(chunkScript);
        Chunk chunk = GD.InstanceFromId(id) as Chunk;

        chunk.SetGenerator(terrainGen);
        chunk.ConstructChunk(chunkSize, x, y, z);
        AddChild(chunk);
        chunks.Add(new Vector3(x, y, z), chunk);
    }
Exemple #4
0
    public void Init(Vector3 position)
    {
        this.noise     = References.noise;
        this.chunkSize = References.chunkSize;
        this.position  = position * chunkSize;
        Translation    = this.position;

        chunkBorders  = (MeshInstance)GetChild(0);
        collisionArea = (Area)GetChild(1);

        chunkBorders.Scale  = new Vector3(References.chunkSize * 0.5f, References.chunkBorderAreaHeight, References.chunkSize * 0.5f);
        collisionArea.Scale = new Vector3(References.chunkSize * 0.5f, References.chunkCollisionAreaHeight, References.chunkSize * 0.5f);
    }
Exemple #5
0
    public override void _Ready()
    {
        Mesh = GetNode <MeshInstance>("MeshInstance");

        ShaderMaterial Mat = new ShaderMaterial();

        Mat.Shader = Items.TileShader;
        Mat.SetShaderParam("texture_albedo", Items.Textures[Type]);
        GetNode <MeshInstance>("MeshInstance").MaterialOverride = Mat;

        CurrentChunkTuple = World.GetChunkTuple(Translation);
        World.AddEntityToChunk(this);
    }
Exemple #6
0
    public void ChangeTexture(Spatial mesh, string name, string newTextureName, Color newColor)
    {
        var          mi = mesh.FindNode(name);
        MeshInstance m  = (MeshInstance)mi;

        SpatialMaterial mat     = new SpatialMaterial();
        var             texture = (Texture)GD.Load(newTextureName);

        mat.AlbedoTexture = texture;
        mat.AlbedoColor   = newColor;

        m.MaterialOverride = mat;
    }
Exemple #7
0
    public override void _Ready()
    {
        red   = (Material)ResourceLoader.Load("res://Assets/Buildings/Outline/OutlineMaterialRed.tres");
        green = (Material)ResourceLoader.Load("res://Assets/Buildings/Outline/OutlineMaterialGreen.tres");

        outline_scene = (PackedScene)ResourceLoader.Load("res://Assets/Buildings/Outline/Outline.tscn");
        outline       = (Spatial)outline_scene.Instance();
        outline.Name  = "Outline";
        outline_mesh  = (MeshInstance)outline.GetNode("luftballonmesherinorotzskelettbaumgraphtankstellenwartjareicht");
        AddChild(outline);

        base._Ready();
    }
    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
    {
        _steeringWheel = this.GetNode("JeepSteeringWheel") as MeshInstance;
        _gear          = this.GetNode("Camera/Panel/Gear") as Label;
        _speed         = this.GetNode("Camera/Panel2/Speed") as Label;
        _gear.Text     = "Park";

        _state = States.Park;
        states[(int)States.Drive]   = new StateDrive(this);
        states[(int)States.Reverse] = new StateReverse(this);
        states[(int)States.Park]    = new StatePark(this);
        Input.SetMouseMode(Input.MouseMode.Captured);
    }
        public void Initialise()
        {
            Report = new DynamicCarReport();
            LastCarModel++;
            if (LastCarModel >= CarModels.Length)
            {
                LastCarModel = 0;
            }
            MeshInstance mesh = (MeshInstance)((PackedScene)GD.Load(CarModels[LastCarModel])).Instance();

            AddChild(mesh);
            _bubble = GetNode <BubbleSprite>("BubbleSprite");
        }
Exemple #10
0
    public override void _Ready()
    {
        GetNode <RigidBody>("DotPhysics").GravityScale = 0;

        dotMesh = GetNode <MeshInstance>("DotPhysics/DotCollision/Dot");
        var mat = new SpatialMaterial();

        mat.AlbedoColor          = Color.FromHsv(1, 1, 1, 0);
        mat.EmissionEnabled      = true;
        mat.Emission             = Color.FromHsv(GD.Randf(), 1, 1);
        mat.EmissionEnergy       = 1;
        dotMesh.MaterialOverride = mat;
    }
Exemple #11
0
    public MeshInstance addPlane(int side)
    {
        MeshInstance p = new MeshInstance {
        };

        p.Mesh = new PlaneMesh {
        };

        Vector3 new_loc = new Vector3(0, 0, 0);
        Vector3 new_rot = new Vector3(0, 0, 0);

        var spread = 1.15f;

        switch (side)
        {
        case side_top:
            new_loc.y = spread;
            break;

        case side_bottom:
            new_rot.x = 180f;
            new_loc.y = -spread;
            break;

        case side_left:
            new_rot.z = -90f;
            new_loc.x = spread;
            break;

        case side_right:
            new_rot.z = 90f;
            new_loc.x = -spread;
            break;

        case side_back:
            new_rot.x = 90f;
            new_loc.z = spread;
            break;

        case side_front:
            new_rot.x = -90f;
            new_loc.z = -spread;
            break;
        }

        p.Scale = new_scale;
        p.Translate(new_loc);
        p.RotationDegrees = new_rot;

        return(p);
    }
Exemple #12
0
    private static MeshInstance DebugMesh()
    {
        SurfaceTool tool = new SurfaceTool();

        tool.Begin(PrimitiveMesh.PrimitiveType.Lines);

        //Front
        tool.AddVertex(new Vector3(0, 0, 0));
        tool.AddVertex(new Vector3(1, 0, 0));
        tool.AddVertex(new Vector3(1, 0, 0));
        tool.AddVertex(new Vector3(1, 1, 0));
        tool.AddVertex(new Vector3(1, 1, 0));
        tool.AddVertex(new Vector3(0, 1, 0));
        tool.AddVertex(new Vector3(0, 1, 0));
        tool.AddVertex(new Vector3(0, 0, 0));

        //Back
        tool.AddVertex(new Vector3(0, 0, 1));
        tool.AddVertex(new Vector3(1, 0, 1));
        tool.AddVertex(new Vector3(1, 0, 1));
        tool.AddVertex(new Vector3(1, 1, 1));
        tool.AddVertex(new Vector3(1, 1, 1));
        tool.AddVertex(new Vector3(0, 1, 1));
        tool.AddVertex(new Vector3(0, 1, 1));
        tool.AddVertex(new Vector3(0, 0, 1));

        //BOTTOM
        tool.AddVertex(new Vector3(0, 0, 0));
        tool.AddVertex(new Vector3(0, 0, 1));
        tool.AddVertex(new Vector3(0, 0, 1));
        tool.AddVertex(new Vector3(1, 0, 1));
        tool.AddVertex(new Vector3(1, 0, 1));
        tool.AddVertex(new Vector3(1, 0, 0));
        tool.AddVertex(new Vector3(1, 0, 0));
        tool.AddVertex(new Vector3(0, 0, 0));

        //TOP
        tool.AddVertex(new Vector3(0, 1, 0));
        tool.AddVertex(new Vector3(0, 1, 1));
        tool.AddVertex(new Vector3(0, 1, 1));
        tool.AddVertex(new Vector3(1, 1, 1));
        tool.AddVertex(new Vector3(1, 1, 1));
        tool.AddVertex(new Vector3(1, 1, 0));
        tool.AddVertex(new Vector3(1, 1, 0));
        tool.AddVertex(new Vector3(0, 1, 0));

        MeshInstance instance = new MeshInstance();

        instance.Mesh = tool.Commit();
        return(instance);
    }
Exemple #13
0
        public InventoryView(
            IPlayerControl playerControl,
            InspectingView viewControl,
            MeshInstance itemStand,
            bool pauseWhenVisible,
            Option <string> closeAction,
            Godot.Control node,
            Tree tree,
            Container buttonContainer,
            Panel infoPanel,
            Label titleLabel,
            Option <Label> typeLabel,
            Option <RichTextLabel> descriptionLabel,
            PackedScene actionButton,
            ILoggerFactory loggerFactory) : base(pauseWhenVisible, closeAction, playerControl, node, loggerFactory)
        {
            Ensure.That(viewControl, nameof(viewControl)).IsNotNull();
            Ensure.That(tree, nameof(tree)).IsNotNull();
            Ensure.That(itemStand, nameof(itemStand)).IsNotNull();
            Ensure.That(buttonContainer, nameof(buttonContainer)).IsNotNull();
            Ensure.That(infoPanel, nameof(infoPanel)).IsNotNull();
            Ensure.That(titleLabel, nameof(titleLabel)).IsNotNull();
            Ensure.That(actionButton, nameof(actionButton)).IsNotNull();

            ViewControl      = viewControl;
            Tree             = tree;
            ButtonContainer  = buttonContainer;
            ItemStand        = itemStand;
            InfoPanel        = infoPanel;
            TitleLabel       = titleLabel;
            TypeLabel        = typeLabel;
            DescriptionLabel = descriptionLabel;
            ActionButton     = actionButton;

            _buttonListeners = new CompositeDisposable();

            OnEquipmentContainerChange = PlayerControl.OnCharacterChange
                                         .Select(c => c.Select(v => v.Equipments).ToObservable())
                                         .Switch();

            OnItemsChange = OnEquipmentContainerChange
                            .Select(c => c.OnItemsChange)
                            .Switch();

            OnSelectionChange = Tree.OnItemSelect()
                                .Select(v => v.Bind(i => Optional(i.GetMeta(SlotKey) as string)))
                                .Merge(OnItemsChange.Select(_ => Option <string> .None))
                                .CombineLatest(OnEquipmentContainerChange, (slot, slots) => (slot, slots))
                                .Select(t => t.slot.Bind(s => t.slots.FindItemInSlot(s)).HeadOrNone())
                                .Do(current => Selected = current);
        }
Exemple #14
0
    private Vector3 get_dimensions(Spatial node)
    {
        MeshInstance node_mesh = new MeshInstance();

        foreach (Spatial child in node.GetChildren())
        {
            // if(child is Godot.MeshInstance)
            // {
            //     node_mesh = (MeshInstance) child;
            // }
        }

        return(new Vector3());
    }
Exemple #15
0
        public override MeshInstance CreateChunkMesh(ref ChunkStruct c)
        {
            // Console.WriteLine("Curr Chunk {0},{1},{2}",c.Dx,c.Dy,c.Dz);
            String startTime = DateTime.Now.ToString("HH:mm:ss:ffff");

            c.surfaceTool.Begin(Mesh.PrimitiveType.Points);
            c.surfaceTool.SetMaterial(mat);
            String initTime = DateTime.Now.ToString("HH:mm:ss:ffff");
            // for (int i = 0; i < CHUNK_SIZE; i += 1)
            // {
            //     for (int j = 0; j < CHUNK_SIZE; j += 1)
            //     {
            //         for (int k = 0; k < CHUNK_SIZE; k += 1)
            //         {
            //             if (c[i, j, k] == 0)
            //             {
            //                 continue;
            //             }
            //             createVoxel(i, j, k, ref c);
            //         }
            //     }
            // }
            int maxChunk = CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE;

            for (int i = 0; i < maxChunk; i++)
            {
                int x = i / (CHUNK_SIZE * CHUNK_SIZE);
                int y = (i / CHUNK_SIZE) % CHUNK_SIZE;
                int z = i % CHUNK_SIZE;
                if (c[x, y, z] == 0)
                {
                    continue;
                }
                createVoxel(x, y, z, ref c);
            }

            String pointCreationTime = DateTime.Now.ToString("HH:mm:ss:ffff");

            c.surfaceTool.Index();
            MeshInstance mesh = new MeshInstance();

            mesh.SetMesh(c.surfaceTool.Commit());
            c.surfaceTool.Clear();
            String indexTime = DateTime.Now.ToString("HH:mm:ss:ffff");

            //  Console.WriteLine("Curr Chunk {0},{1},{2} Curr Thread: {3}, StartTime: {4}, Initialization Time: {5}, Greedy Time: {6}, Index Time {7}",c.Dx,c.Dy,c.Dz,
            //  System.Threading.Thread.CurrentThread.ManagedThreadId,startTime
            // ,initTime,pointCreationTime,indexTime);
            return(mesh);
        }
    public static Mesh Combine(MeshInstance[] _combines) {
        Mesh mesh = new Mesh();
        mesh.name = "Combined Mesh";

        CombineInstance[] combineInsts = new CombineInstance[_combines.Length];
        int i = 0;
        while (i < _combines.Length) {
            combineInsts[i].mesh = _combines[i].mesh;
            combineInsts[i].transform = _combines[i].transform;
            ++i;
        }
        mesh.CombineMeshes(combineInsts);
        return mesh;
    }
Exemple #17
0
    private static int getIndex(Dictionary <int, int> indexTranslation, MeshInstance meshInstance, int inputVert, List <Vector3> vertices, List <Vector3> normals, List <Vector4> tangents, List <Vector2> uvs, List <Vector2> uv2s, List <Vector2> uv3s, List <Color> colors, Vector3[] inputVertices, Vector3[] inputNormals, Vector4[] inputTangents, Vector2[] inputUVs, Color[] inputColors, Vector2?uv2Force, Vector2?uv3Force)
    {
        int newVert;

        if (indexTranslation.ContainsKey(inputVert))
        {
            newVert = indexTranslation[inputVert];
        }
        else
        {
            newVert = vertices.Count;
            indexTranslation[inputVert] = newVert;
            vertices.Add(meshInstance.transform.MultiplyPoint(inputVertices[inputVert]));

            Matrix4x4 invTranspose = meshInstance.transform;
            invTranspose = invTranspose.inverse.transpose;
            normals.Add(invTranspose.MultiplyVector(inputNormals[inputVert]).normalized);
            Vector4 p4 = inputTangents[inputVert];
            Vector3 p  = new Vector3(p4.x, p4.y, p4.z);
            p = invTranspose.MultiplyVector(p).normalized;
            tangents.Add(invTranspose.MultiplyVector(new Vector4(p.x, p.y, p.z, p4.w)));
            uvs.Add(meshInstance.uv1Transform.MultiplyPoint(inputUVs[inputVert]));
            if (!uv2Force.HasValue)
            {
                uv2s.Add(meshInstance.uv2Transform.MultiplyPoint(inputUVs[inputVert]));
            }
            else
            {
                uv2s.Add(uv2Force.Value);
            }

            if (!uv3Force.HasValue)
            {
                uv3s.Add(meshInstance.uv3Transform.MultiplyPoint(inputUVs[inputVert]));
            }
            else
            {
                uv3s.Add(uv3Force.Value);
            }
            if (inputColors.Length > 0)
            {
                colors.Add(meshInstance.color.linear * inputColors[inputVert]);
            }
            else
            {
                colors.Add(meshInstance.color.linear);
            }
        }
        return(newVert);
    }
    // Function that is called when the selected object is changed
    // Connected to the "ObjectSelectList" option button through the editor
    public void _on_ObjectSelectList_item_selected(int index)
    {
        // Hide the previously selected object
        objectMesh.Visible = false;

        // Set the current object's index
        currentObjectIndex = index;

        // Reassign the selected mesh instance to the new object
        objectMesh = objectMeshRoot.GetChild <MeshInstance>(FIRST_OBJECT_INDEX + currentObjectIndex);

        // Show the new object
        objectMesh.Visible = true;
    }
Exemple #19
0
    public override void _Ready()
    {
        System  = new PipeSystem(this);
        Friends = new HashSet <PipeCoreLogic>();

        Position1        = GetNode <Spatial>("Positions/Position1");
        OpenEndMesh      = GetNode <MeshInstance>("OpenEndMesh");
        OpenEndCollision = GetNode <CollisionShape>("OpenEndCollision");
        OpenEnd          = GetNode <StaticBody>("OpenEnd");

        CallDeferred(nameof(GridUpdate));

        base._Ready();
    }
    /// <summary>
    /// Add a mesh instance to the combiner.
    /// </summary>
    /// <param name="instance">The mesh instance to add.</param>
    public void AddMeshInstance(MeshInstance instance)
    {
        int baseVertexIndex = _vertices.Count;

        PrepareForAddingVertices(instance.mesh.vertexCount);

        _vertices.AddRange(instance.mesh.vertices.Select(v => instance.transform.MultiplyPoint(v)));
        _normals.AddRange(
            instance.mesh.normals.Select(n => instance.transform.inverse.transpose.MultiplyVector(n).normalized));
        _tangents.AddRange(instance.mesh.tangents.Select(t =>
        {
            var p = new Vector3(t.x, t.y, t.z);
            p     =
                instance.transform.inverse.transpose.
                MultiplyVector(p).normalized;
            return(new Vector4(p.x, p.y, p.z, t.w));
        }));
        _uv.AddRange(instance.mesh.uv);
        _uv1.AddRange(instance.mesh.uv1);
        _colors.AddRange(instance.mesh.colors);

        if (_generateStrips)
        {
            int[] inputstrip = instance.mesh.GetTriangleStrip(instance.subMeshIndex);
            PrepareForAddingStrips(instance.targetSubMeshIndex, new[] { inputstrip.Length });
            List <int> outputstrip = _strip[instance.targetSubMeshIndex];
            if (outputstrip.Count != 0)
            {
                if ((outputstrip.Count & 1) == 1)
                {
                    outputstrip.Add(outputstrip[outputstrip.Count - 1]);
                    outputstrip.Add(inputstrip[0] + baseVertexIndex);
                    outputstrip.Add(inputstrip[0] + baseVertexIndex);
                }
                else
                {
                    outputstrip.Add(outputstrip[outputstrip.Count - 1]);
                    outputstrip.Add(inputstrip[0] + baseVertexIndex);
                }
            }

            outputstrip.AddRange(inputstrip.Select(s => s + baseVertexIndex));
        }
        else
        {
            int[] inputtriangles = instance.mesh.GetTriangles(instance.subMeshIndex);
            PrepareForAddingTriangles(instance.targetSubMeshIndex, inputtriangles.Length);
            _triangles[instance.targetSubMeshIndex].AddRange(inputtriangles.Select(t => t + baseVertexIndex));
        }
    }
Exemple #21
0
    void CombinaQuads()
    {
        MeshInstance cube = new MeshInstance
        {
            Name = "Chunk"
        };

        ArrayMesh cubeArray = new ArrayMesh();

        Godot.Collections.Array kids = chunk.GetChildren();
        Material[] materiais         = new Material[kids.Count];

        int contador = 0;

        foreach (MeshInstance meshI in kids)
        {
            Vector3[] vertLocal  = (Vector3[])meshI.Mesh.SurfaceGetArrays(0)[(int)ArrayMesh.ArrayType.Vertex];
            Vector3[] vertGlobal = new Vector3[vertLocal.Length];

            //convertendo as coordenads de locais para globais dos quads
            for (int i = 0; i < vertLocal.Length; i++)
            {
                vertGlobal[i].x = vertLocal[i].x + meshI.Translation.x;
                vertGlobal[i].y = vertLocal[i].y + meshI.Translation.y;
                vertGlobal[i].z = vertLocal[i].z + meshI.Translation.z;
            }

            ArrayMesh combineArray = new ArrayMesh();
            var       arrays       = new Godot.Collections.Array();
            arrays.Resize((int)ArrayMesh.ArrayType.Max);
            arrays[(int)ArrayMesh.ArrayType.Vertex] = vertGlobal;
            arrays[(int)ArrayMesh.ArrayType.Normal] = meshI.Mesh.SurfaceGetArrays(0)[(int)ArrayMesh.ArrayType.Normal];
            arrays[(int)ArrayMesh.ArrayType.TexUv]  = meshI.Mesh.SurfaceGetArrays(0)[(int)ArrayMesh.ArrayType.TexUv];
            arrays[(int)ArrayMesh.ArrayType.Index]  = meshI.Mesh.SurfaceGetArrays(0)[(int)ArrayMesh.ArrayType.Index];

            cubeArray.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
            materiais[contador] = meshI.GetSurfaceMaterial(0);

            meshI.QueueFree();
            contador++;
        }

        cube.Mesh = cubeArray;
        for (int i = 0; i < materiais.Length; i++)
        {
            cube.SetSurfaceMaterial(i, materiais[i]);
        }

        chunk.AddChild(cube);
    }
Exemple #22
0
    public void CreateLeaf()
    {
        SphereMesh mesh = new SphereMesh();

        mesh.Radius         = 0.4f;
        mesh.Height         = mesh.Radius * 2;
        mesh.RadialSegments = 8;
        mesh.Rings          = 4;
        MeshInstance meshInstance = new MeshInstance();

        meshInstance.Mesh = mesh;
        meshInstance.SetSurfaceMaterial(0, LeafMaterial);
        AddChild(meshInstance);
    }
    /// <summary>
    /// Add a mesh instance to the combiner.
    /// </summary>
    /// <param name="instance">The mesh instance to add.</param>
    public void AddMeshInstance(MeshInstance instance)
    {
        int baseVertexIndex = _vertices.Count;

        PrepareForAddingVertices(instance.mesh.vertexCount);

        _vertices.AddRange(instance.mesh.vertices.Select(v => instance.transform.MultiplyPoint(v)));
        _normals.AddRange(
            instance.mesh.normals.Select(n => instance.transform.inverse.transpose.MultiplyVector(n).normalized));
        _tangents.AddRange(instance.mesh.tangents.Select(t =>
                                                             {
                                                                 var p = new Vector3(t.x, t.y, t.z);
                                                                 p =
                                                                     instance.transform.inverse.transpose.
                                                                         MultiplyVector(p).normalized;
                                                                 return new Vector4(p.x, p.y, p.z, t.w);
                                                             }));
        _uv.AddRange(instance.mesh.uv);
        _uv1.AddRange(instance.mesh.uv1);
        _colors.AddRange(instance.mesh.colors);

        if (_generateStrips)
        {
            int[] inputstrip = instance.mesh.GetTriangles(instance.subMeshIndex);
            PrepareForAddingStrips(instance.targetSubMeshIndex, new[] {inputstrip.Length});
            List<int> outputstrip = _strip[instance.targetSubMeshIndex];
            if (outputstrip.Count != 0)
            {
                if ((outputstrip.Count & 1) == 1)
                {
                    outputstrip.Add(outputstrip[outputstrip.Count - 1]);
                    outputstrip.Add(inputstrip[0] + baseVertexIndex);
                    outputstrip.Add(inputstrip[0] + baseVertexIndex);
                }
                else
                {
                    outputstrip.Add(outputstrip[outputstrip.Count - 1]);
                    outputstrip.Add(inputstrip[0] + baseVertexIndex);
                }
            }

            outputstrip.AddRange(inputstrip.Select(s => s + baseVertexIndex));
        }
        else
        {
            int[] inputtriangles = instance.mesh.GetTriangles(instance.subMeshIndex);
            PrepareForAddingTriangles(instance.targetSubMeshIndex, inputtriangles.Length);
            _triangles[instance.targetSubMeshIndex].AddRange(inputtriangles.Select(t => t + baseVertexIndex));
        }
    }
Exemple #24
0
    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
    {
        // Get references to parts of tanks
        trackleft  = (MeshInstance)GetNode("TrackLeft");
        trackright = (MeshInstance)GetNode("TrackRight");
        body       = (MeshInstance)GetNode("Body");
        turret     = (KinematicBody)GetNode("Turret");
        gun        = (MeshInstance)GetNode("Turret/TurretMesh/Gun");

        // load sounds
        trackmovementsound = (AudioStreamPlayer3D)GetNode("SoundGroup/TrackMovementSound");
        firesound          = (AudioStreamPlayer3D)GetNode("SoundGroup/FireSound");
        explodesound       = (AudioStreamPlayer3D)GetNode("SoundGroup/ExplosionSound");
        soundgroup         = GetNode("SoundGroup");

        // load cameras
        thirdpersoncamera = (Camera)GetNode("ThirdPersonCam");
        firstpersoncamera = (Camera)GetNode("Turret/TurretMesh/Gun/BulletSpawn/Camera");

        // reference to explosion for death
        explosion = (Particles)GetNode("Explosion/Particles");
        explosion.SetEmitting(false);

        // Load bullet scene
        bulletscene = ResourceLoader.Load("res://Bullet.tscn") as Godot.PackedScene;

        // Set a color for the tank
        setTankColor(defaultTankColor);

        health = maxhealth;

        // add signals
        AddUserSignal("dec_local_health");
        AddUserSignal("respawn");
        AddUserSignal("bullet_fired");

        // connect respawn timer
        AddChild(deathtimer);
        deathtimer.Connect("timeout", this, "Respawn");
        deathtimer.SetWaitTime(RESPAWN_SECONDS);

        SetProcess(true);

        // required to appear at spawn
        MoveAndSlide(new Vector3(0, 0, 0), new Vector3(0, 1, 0), true);

        // enforce no flying tanks issue #20
        originalY = Transform.origin.y;
    }
Exemple #25
0
 void find_LODs()
 {
     Godot.Collections.Array childrens = this.GetChildren();
     foreach (Node child in childrens)
     {
         string name = child.Name;
         if (name.Contains("_LOD1"))
         {
             LOD1_Inst = (MeshInstance)child;
         }
         else if (name.Contains("_LOD2"))
         {
             LOD2_Inst = (MeshInstance)child;
         }
         else if (name.Contains("_LOD3"))
         {
             LOD3_Inst = (MeshInstance)child;
         }
         else if (name.Contains("_LOD0"))
         {
             LOD0_Inst = (MeshInstance)child;
         }
         else if (!name.Contains("_Coll"))
         {
             //LOD0_Inst = (MeshInstance)child;
         }
     }
     LOD_Num = 4;
     if (LOD3_Inst == null)
     {
         LOD3_Inst = new MeshInstance();
         LOD_Num   = 3;
     }
     if (LOD2_Inst == null)
     {
         LOD2_Inst = new MeshInstance();
         LOD_Num   = 2;
     }
     if (LOD1_Inst == null)
     {
         LOD1_Inst = new MeshInstance();
         LOD_Num   = 1;
     }
     if (LOD0_Inst == null)
     {
         LOD0_Inst = new MeshInstance();
         LOD_Num   = 0;
     }
 }
Exemple #26
0
    public override void _Ready()
    {
        Joint = GetNode <Spatial>("EverythingJoint");
        Mesh  = Joint.GetNode <MeshInstance>("Mesh");
        Head  = Joint.GetNode <Hitbox>("HeadHitbox");
        Feet  = Joint.GetNode <Hitbox>("FeetHitbox");

        CamJoint = GetNode <Spatial>("CamJoint");
        Cam      = CamJoint.GetNode <Camera>("Cam");
        Holder   = Cam.GetNode <WeaponHolder>("WeaponHolder");

        Cam.Current = false;

        base._Ready();
    }
        private Action <object> ActionCreateChunkMesh(Tuple <int, int, int> value)
        {
            return(t =>
            {
                if (t == null)
                {
                    throw new ArgumentNullException(nameof(t));
                }

                // Tuple<int, int, int> value = t1;
                // Console.WriteLine("{0},{1},{2}", value.Item1, value.Item2, value.Item3);
                MeshInstance mesh = this.mesher.CreateChunkMesh(ref this.chunksList[value.Item1, value.Item2, value.Item3]);
                this.chunkQueue.Enqueue(mesh);
            });
        }
        /**
         * Start auto loding
         */
        public static ArrayMesh generateMesh(float quality, MeshInstance origMeshInst)
        {
            var arr_mesh  = new ArrayMesh();
            var arrayMesh = origMeshInst.Mesh as ArrayMesh;

            quality = MathHelper.Clamp01(quality);

            for (int i = 0; i < origMeshInst.Mesh.GetSurfaceCount(); i++)
            {
                var arrays = generateMeshFromSurface(quality, origMeshInst, i);
                arr_mesh.AddSurfaceFromArrays(Godot.Mesh.PrimitiveType.Triangles, arrays);
            }

            return(arr_mesh);
        }
Exemple #29
0
    public static void DrawSphere(Vector3 globalLocation, Spatial parent, float diameter = 0.05f)
    {
        MeshInstance sphere = new MeshInstance();
        SphereMesh   shape  = new SphereMesh();

        parent.AddChild(sphere);
        Transform placeholder = sphere.GlobalTransform;

        placeholder.origin     = globalLocation;
        sphere.GlobalTransform = placeholder;
        shape.Radius           = diameter / 2.0f;
        shape.Height           = diameter;
        sphere.Mesh            = shape;
        sphere.Visible         = true;
    }
Exemple #30
0
    public void CreateQuad(Vector3 vertex0, Vector3 vertex1, Vector3 vertex2, Vector3 vertex3)
    {
        // Generate quad mesh (2 triangles)

        Vector3[] vertices = { vertex0,   //top-left
                               vertex1,   //top-right
                               vertex2,   //bottom-left
                               vertex3 }; //bottom-right

        int[] index = new int[6] {
            0, 1, 2, 3, 2, 1
        };

        // UVs
        Vector2[] uvs = { new Vector2(0f, 1f),   //top-left
                          new Vector2(1f, 1f),   //top-right
                          new Vector2(0f, 0f),   //bottom-left
                          new Vector2(1f, 0f) }; //bottom-right

        // Normals
        Vector3[] normals = new Vector3[4]
        {
            Vector3.Up, Vector3.Up, Vector3.Up, Vector3.Up
        };

        Godot.Collections.Array arrays = new Godot.Collections.Array();
        arrays.Resize(9);
        // see
        arrays[0] = vertices;
        arrays[1] = normals;
        arrays[4] = uvs;
        arrays[8] = index;

        // Create the Mesh.

        // Initialize the ArrayMesh.
        ArrayMesh arr_mesh = new ArrayMesh();

        arr_mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
        MeshInstance quad = new MeshInstance();

        quad.Mesh = arr_mesh;

        quad.MaterialOverride = cubeMaterial; // apply texture - rock, dirt, grass, etc.
        quad.MaterialOverride = cubeMaterial; // apply texture - rock, dirt, grass, etc.

        cube.AddChild(quad);                  // add quad to the cube node
    }
Exemple #31
0
        // public override MeshInstance CreateChunkMesh(ref ChunkStruct c)
        // {

        //     // c.chunkData = SnappyCodec.Uncompress(c.compChunkData);
        //     c.surfaceTool.Begin(Mesh.PrimitiveType.Triangles);
        //     c.surfaceTool.SetMaterial(mat);
        //     for (int i = 0; i < CHUNK_SIZE; i++)
        //     {
        //         for (int j = 0; j < CHUNK_SIZE; j++)
        //         {
        //             for (int k = 0; k < CHUNK_SIZE; k++)
        //             {
        //                 if (c[i, j, k] == 0)
        //                 {
        //                     continue;
        //                 }
        //                 createFaces(i, j, k, c.Dx, c.Dy, c.Dz, ref c.surfaceTool, ref c);
        //             }
        //         }
        //     }
        //     c.surfaceTool.Index();
        //     MeshInstance mesh = new MeshInstance();
        //     mesh.SetMesh(c.surfaceTool.Commit());
        //     c.surfaceTool.Clear();
        //     // c.chunkData = new byte[1];
        //     return mesh;
        // }



        public override MeshInstance CreateChunkMesh(ref ChunkStruct c)
        {
            String startTime = DateTime.Now.ToString("HH:mm:ss:ffff");

            byte[][]     firstMask;
            byte[][]     secondMask;
            MeshInstance mesh = new MeshInstance();

            c.surfaceTool.Begin(Mesh.PrimitiveType.Triangles);
            c.surfaceTool.SetMaterial(mat);
            firstMask  = new byte[CHUNK_SIZE][];
            secondMask = new byte[CHUNK_SIZE][];
            initializeJaggedArr(ref firstMask);
            initializeJaggedArr(ref secondMask);
            String initTime = DateTime.Now.ToString("HH:mm:ss:ffff");

            for (int x = 0; x < CHUNK_SIZE; x++)
            {
                this.FillMasksWithLeftRight(ref c, x, ref firstMask, ref secondMask);

                this.FillWithQuads(firstMask, x, ref c, CreateLeftQuad);
                this.FillWithQuads(secondMask, x + 1, ref c, CreateRightQuad);
            }
            for (int y = 0; y < CHUNK_SIZE; y++)
            {
                this.FillMasksWithBottomTop(ref c, y, ref firstMask, ref secondMask);

                this.FillWithQuads(firstMask, y, ref c, CreateBottomQuad);
                this.FillWithQuads(secondMask, y + 1, ref c, CreateTopQuad);
            }
            for (int z = 0; z < CHUNK_SIZE; z++)
            {
                this.FillMasksWithBackFront(ref c, z, ref firstMask, ref secondMask);

                this.FillWithQuads(firstMask, z, ref c, CreateBackQuad);
                this.FillWithQuads(secondMask, z + 1, ref c, CreateFrontQuad);
            }
            String greedyMeshingTime = DateTime.Now.ToString("HH:mm:ss:ffff");

            c.surfaceTool.Index();
            mesh.SetMesh(c.surfaceTool.Commit());
            c.surfaceTool.Clear();
            String indexTime = DateTime.Now.ToString("HH:mm:ss:ffff");

            Console.WriteLine("Curr Thread: {0}, StartTime: {1}, Initialization Time: {2}, Greedy Time: {3}, Index Time {4}", System.Threading.Thread.CurrentThread.ManagedThreadId, startTime
                              , initTime, greedyMeshingTime, indexTime);
            return(mesh);
        }
Exemple #32
0
 public GroundNode(MeshInstance meshInstance) : base()
 {
     this.meshInstance = meshInstance;
     Godot.Collections.Array children = meshInstance.GetChildren();
     foreach (var child in children)
     {
         if (child is CollisionObject collider)
         {
             collider.Connect("input_event", this, nameof(this.onInputEvent));
             collider.Connect("mouse_entered", this, nameof(this.onMouseEntered));
             collider.Connect("mouse_exited", this, nameof(this.onMouseExited));
             break;
         }
     }
     // meshInstance.MaterialOverride = new
 }
	public static Mesh Combine (MeshInstance[] combines, bool generateStrips)
	{
		int vertexCount = 0;
		int triangleCount = 0;
		int stripCount = 0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				vertexCount += combine.mesh.vertexCount;
				
				if (generateStrips)
				{
					#if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9
					int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length;
					#endif

					#if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5
					int curStripCount = combine.mesh.GetTriangles(combine.subMeshIndex).Length;
					#endif

					if (curStripCount != 0)
					{
						if( stripCount != 0 )
						{
							if ((stripCount & 1) == 1 )
								stripCount += 3;
							else
								stripCount += 2;
						}
						stripCount += curStripCount;
					}
					else
					{
						generateStrips = false;
					}
				}
			}
		}
		
		if (!generateStrips)
		{
			foreach( MeshInstance combine in combines )
			{
				if (combine.mesh)
				{
					#if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9
					triangleCount += combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length;
					#endif

					#if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5
					triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;
					#endif
				}
			}
		}
		
		Vector3[] vertices = new Vector3[vertexCount] ;
		Vector3[] normals = new Vector3[vertexCount] ;
		Vector4[] tangents = new Vector4[vertexCount] ;
		Vector2[] uv = new Vector2[vertexCount];
		Vector2[] uv1 = new Vector2[vertexCount];
		Color[] colors = new Color[vertexCount];
		
		int[] triangles = new int[triangleCount];
		int[] strip = new int[stripCount];
		
		int offset;
		
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);
		}

		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				Matrix4x4 invTranspose = combine.transform;
				invTranspose = invTranspose.inverse.transpose;
				CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);
			}
				
		}
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				Matrix4x4 invTranspose = combine.transform;
				invTranspose = invTranspose.inverse.transpose;
				CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);
			}
				
		}
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);
		}
		
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				Copy(combine.mesh.vertexCount, combine.mesh.uv2, uv1, ref offset);
		}
		
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset);
		}
		
		int triangleOffset=0;
		int stripOffset=0;
		int vertexOffset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				if (generateStrips)
				{
					#if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9
					int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex);
					#endif

					#if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5
					int[] inputstrip = combine.mesh.GetTriangles(combine.subMeshIndex);
					#endif

					if (stripOffset != 0)
					{
						if ((stripOffset & 1) == 1)
						{
							strip[stripOffset+0] = strip[stripOffset-1];
							strip[stripOffset+1] = inputstrip[0] + vertexOffset;
							strip[stripOffset+2] = inputstrip[0] + vertexOffset;
							stripOffset+=3;
						}
						else
						{
							strip[stripOffset+0] = strip[stripOffset-1];
							strip[stripOffset+1] = inputstrip[0] + vertexOffset;
							stripOffset+=2;
						}
					}
					
					for (int i=0;i<inputstrip.Length;i++)
					{
						strip[i+stripOffset] = inputstrip[i] + vertexOffset;
					}
					stripOffset += inputstrip.Length;
				}
				else
				{
					#if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9
					int[]  inputtriangles = combine.mesh.GetTriangleStrip(combine.subMeshIndex);
					#endif

					#if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5
					int[]  inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);
					#endif

					for (int i=0;i<inputtriangles.Length;i++)
					{
						triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset;
					}
					triangleOffset += inputtriangles.Length;
				}
				
				vertexOffset += combine.mesh.vertexCount;
			}
		}
		
		Mesh mesh = new Mesh();
		mesh.name = "Combined Mesh";
		mesh.vertices = vertices;
		mesh.normals = normals;
		mesh.colors = colors;
		mesh.uv = uv;
		mesh.uv2 = uv1;
		mesh.tangents = tangents;
		if (generateStrips)
			#if UNITY_4_2 || UNITY_4_5 || UNITY_4_6 || UNITY_4_7 || UNITY_4_8 || UNITY_4_9
			mesh.SetTriangleStrip(strip, 0);
			#endif

			#if UNITY_5_0 || UNITY_5_1 || UNITY_5_2 || UNITY_5_3 || UNITY_5_4 || UNITY_5_5
			mesh.SetTriangles(strip, 0);
			#endif
		else
			mesh.triangles = triangles;
		
		return mesh;
	}
    public static Mesh Combine(MeshInstance[] combines, bool generateStrips)
    {
        int vertexCount = 0;
        int triangleCount = 0;
        int stripCount = 0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
            {
                vertexCount += combine.mesh.vertexCount;

                if (generateStrips)
                {
                    // SUBOPTIMAL FOR PERFORMANCE
                    //int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length;
                    int curStripCount = combine.mesh.GetTriangles(combine.subMeshIndex).Length;

                    if (curStripCount != 0)
                    {
                        if( stripCount != 0 )
                        {
                            if ((stripCount & 1) == 1 )
                                stripCount += 3;
                            else
                                stripCount += 2;
                        }
                        stripCount += curStripCount;
                    }
                    else
                    {
                        generateStrips = false;
                    }
                }
            }
        }

        // Precomputed how many triangles we need instead
        if (!generateStrips)
        {
            foreach( MeshInstance combine in combines )
            {
                if (combine.mesh)
                {
                    triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;
                }
            }
        }

        Vector3[] vertices = new Vector3[vertexCount] ;
        Vector3[] normals = new Vector3[vertexCount] ;
        Vector4[] tangents = new Vector4[vertexCount] ;
        Vector2[] uv = new Vector2[vertexCount];
        Vector2[] uv1 = new Vector2[vertexCount];
        Color[] colors = new Color[vertexCount];

        int[] triangles = new int[triangleCount];
        int[] strip = new int[stripCount];

        int offset;

        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
                Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);
        }

        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
            {
                Matrix4x4 invTranspose = combine.transform;
                invTranspose = invTranspose.inverse.transpose;
                CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);
            }

        }
        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
            {
                Matrix4x4 invTranspose = combine.transform;
                invTranspose = invTranspose.inverse.transpose;
                CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);
            }

        }
        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
                Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);
        }

        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
                Copy(combine.mesh.vertexCount, combine.mesh.uv1, uv1, ref offset);
        }

        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
                CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset);
        }

        int triangleOffset=0;
        int stripOffset=0;
        int vertexOffset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
            {
                if (generateStrips)
                {
                    //int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex);
                    int[] inputstrip = combine.mesh.GetTriangles(combine.subMeshIndex);
                    if (stripOffset != 0)
                    {
                        if ((stripOffset & 1) == 1)
                        {
                            strip[stripOffset+0] = strip[stripOffset-1];
                            strip[stripOffset+1] = inputstrip[0] + vertexOffset;
                            strip[stripOffset+2] = inputstrip[0] + vertexOffset;
                            stripOffset+=3;
                        }
                        else
                        {
                            strip[stripOffset+0] = strip[stripOffset-1];
                            strip[stripOffset+1] = inputstrip[0] + vertexOffset;
                            stripOffset+=2;
                        }
                    }

                    for (int i=0;i<inputstrip.Length;i++)
                    {
                        strip[i+stripOffset] = inputstrip[i] + vertexOffset;
                    }
                    stripOffset += inputstrip.Length;
                }
                else
                {
                    int[]  inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);
                    for (int i=0;i<inputtriangles.Length;i++)
                    {
                        triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset;
                    }
                    triangleOffset += inputtriangles.Length;
                }

                vertexOffset += combine.mesh.vertexCount;
            }
        }

        Mesh mesh = new Mesh();
        mesh.name = "Combined Mesh";
        mesh.vertices = vertices;
        mesh.normals = normals;
        mesh.colors = colors;
        mesh.uv = uv;
        mesh.uv1 = uv1;
        mesh.tangents = tangents;
        if (generateStrips)
            //mesh.SetTriangleStrip(strip, 0);
            mesh.SetTriangles(strip, 0);
        else
            mesh.triangles = triangles;

        return mesh;
    }
    public static Mesh Combine(MeshInstance[] combines)
    {
        int vertexCount = 0;
        int triangleCount = 0;

        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
            {
                vertexCount += combine.mesh.vertexCount;
            }
        }

        // Precomputed how many triangles we need instead

        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
            {
                triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;
            }
        }

        Vector3[] vertices = new Vector3[vertexCount] ;
        Vector3[] normals = new Vector3[vertexCount] ;
        Vector4[] tangents = new Vector4[vertexCount] ;
        Vector2[] uv = new Vector2[vertexCount];
        Vector2[] uv1 = new Vector2[vertexCount];

        int offset;

        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
                Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);
        }

        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
            {
                Matrix4x4 invTranspose = combine.transform;
                invTranspose = invTranspose.inverse.transpose;
                CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);
            }

        }
        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
            {
                Matrix4x4 invTranspose = combine.transform;
                invTranspose = invTranspose.inverse.transpose;
                CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);
            }

        }
        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
                Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);
        }

        offset=0;
        foreach( MeshInstance combine in combines )
        {
            if (combine.mesh)
                Copy(combine.mesh.vertexCount, combine.mesh.uv1, uv1, ref offset);
        }

        int triangleOffset=0;
        int vertexOffset=0;

        int j=0;

        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.normals = normals;
        mesh.uv = uv;
        mesh.uv1 = uv1;
        mesh.tangents = tangents;

        //Setting SubMeshes
        mesh.subMeshCount = combines.Length;

        foreach( MeshInstance combine in combines )
        {
            int[]  inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);
            int[] trianglesx = new int[inputtriangles.Length];
            for (int i=0;i<inputtriangles.Length;i++)
            {
                //triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset;
                trianglesx[i] = inputtriangles[i] + vertexOffset;
            }
            triangleOffset += inputtriangles.Length;
            mesh.SetTriangles(trianglesx,j++);

            vertexOffset += combine.mesh.vertexCount;
        }

        mesh.name = "Combined Mesh";

        return mesh;
    }
    public static MeshData ColorCombine(MeshInstance[] combines, out bool success)
    {
        int length = combines.Length;
        int vertexCount = 0;
        int triangleCount = 0;
        int maxVertices = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                int count = combines[combIndex].meshData.vertexCount;
                vertexCount += count;
                if (maxVertices < count)
                    maxVertices = count;
            }
        }
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                triangleCount += combines[combIndex].meshData.triangles.Length;
            }
        }

        List<Vector3> vertices = new List<Vector3>(vertexCount);
        List<Vector3> normals = new List<Vector3>(vertexCount);
        List<Vector4> tangents = new List<Vector4>(vertexCount);
        List<Vector2> uvs = new List<Vector2>(vertexCount);
        List<Vector2> uv2s = new List<Vector2>(vertexCount);
        List<Color> colors = new List<Color>(vertexCount);

        Dictionary<int, int> indexTranslation = new Dictionary<int, int>(maxVertices);

        List<int> triangles = new List<int>(triangleCount);

        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                int[] inputtriangles = combines[combIndex].meshData.triangles;
                var inputVertices = combines[combIndex].meshData.vertices;
                var inputNormals = combines[combIndex].meshData.normals;
                var inputUVs = combines[combIndex].meshData.uv;
                var inputColors = combines[combIndex].meshData.colors;
                var inputTangents = combines[combIndex].meshData.tangents;
                int copiedTriangles = 0;
                for (int i = 0; i < inputtriangles.Length; i += 3)
                {
                    int vert0 = inputtriangles[i + 0];
                    int vert1 = inputtriangles[i + 1];
                    int vert2 = inputtriangles[i + 2];
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.Up) == HiddenFaces.Up)
                        && (inputVertices[vert0].y > topThreshold)
                        && (inputVertices[vert1].y > topThreshold)
                        && (inputVertices[vert2].y > topThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.Down) == HiddenFaces.Down)
                        && (inputVertices[vert0].y < -topThreshold)
                        && (inputVertices[vert1].y < -topThreshold)
                        && (inputVertices[vert2].y < -topThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.North) == HiddenFaces.North)
                        && (inputVertices[vert0].z > sideThreshold)
                        && (inputVertices[vert1].z > sideThreshold)
                        && (inputVertices[vert2].z > sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.South) == HiddenFaces.South)
                        && (inputVertices[vert0].z < -sideThreshold)
                        && (inputVertices[vert1].z < -sideThreshold)
                        && (inputVertices[vert2].z < -sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.East) == HiddenFaces.East)
                        && (inputVertices[vert0].x > sideThreshold)
                        && (inputVertices[vert1].x > sideThreshold)
                        && (inputVertices[vert2].x > sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.West) == HiddenFaces.West)
                        && (inputVertices[vert0].x < -sideThreshold)
                        && (inputVertices[vert1].x < -sideThreshold)
                        && (inputVertices[vert2].x < -sideThreshold))
                        continue;

                    int newVert0 = getIndex(indexTranslation, combines[combIndex], vert0, vertices, normals, tangents, uvs, uv2s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors);
                    int newVert1 = getIndex(indexTranslation, combines[combIndex], vert1, vertices, normals, tangents, uvs, uv2s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors);
                    int newVert2 = getIndex(indexTranslation, combines[combIndex], vert2, vertices, normals, tangents, uvs, uv2s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors);

                    if (newVert0 > 65532 || newVert1 > 65532 || newVert2 > 65532)
                        goto failure;

                    triangles.Add(newVert0);
                    triangles.Add(newVert1);
                    triangles.Add(newVert2);
                    copiedTriangles += 3;
                }
            }
            indexTranslation.Clear();
        }
        success = true;
        return new MeshData(
            vertices: vertices.ToArray(),
            normals: normals.ToArray(),
            tangents: tangents.ToArray(),
            uv: uvs.ToArray(),
            uv2: uv2s.ToArray(),
            colors: colors.ToArray(),
            triangles: triangles.ToArray()
            );
        failure:
        success = false;
        return new MeshData(
            vertices: vertices.ToArray(),
            normals: normals.ToArray(),
            tangents: tangents.ToArray(),
            uv: uvs.ToArray(),
            uv2: uv2s.ToArray(),
            colors: colors.ToArray(),
            triangles: triangles.ToArray()
            );
    }
        public static ControlCombineChildrenINfiniDyGrass.Meshy CombineM(int ID,List<int> Has_mesh,bool thread_started, MeshInstance[] combines, bool generateStrips, int vertexCount, int triangleCount,List<int> Combine_Mesh_vertexCount,List<Vector3[]> Combine_Mesh_vertices,List<Vector3[]> Combine_Mesh_normals,List<Vector4[]> Combine_Mesh_tangets, List<Vector2[]> Combine_Mesh_uv,List<Vector2[]> Combine_Mesh_uv1,List<Color[]> Combine_Mesh_colors,List<int[]> Combine_Mesh_triangles)
        {
            Vector3[] vertices = new Vector3[vertexCount] ;
            Vector3[] normals = new Vector3[vertexCount] ;
            Vector4[] tangents = new Vector4[vertexCount] ;
            Vector2[] uv = new Vector2[vertexCount];
            Vector2[] uv1 = new Vector2[vertexCount];
            Color[] colors = new Color[vertexCount];
            int[] triangles = new int[triangleCount];
            int offset;

            offset=0;

            int count = 0 ;
            foreach( MeshInstance combine in combines )
            {

                if(Has_mesh[count] == 1){
                    Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_vertices[count], vertices, ref offset, combine.transform);
                }

                count++;
            }

            offset=0;
            count = 0 ;
            foreach( MeshInstance combine in combines )
            {
                //if (combine.mesh)
                if(Has_mesh[count] == 1)
                {
                    Matrix4x4 invTranspose = combine.transform;
                    invTranspose = invTranspose.inverse.transpose;
                    CopyNormal(Combine_Mesh_vertexCount[count], Combine_Mesh_normals[count], normals, ref offset, invTranspose);
                    count++;
                }
            }

            offset=0;
            count = 0 ;
            foreach( MeshInstance combine in combines )
            {

                if(Has_mesh[count] == 1)
                {
                    Matrix4x4 invTranspose = combine.transform;
                    invTranspose = invTranspose.inverse.transpose;
                    CopyTangents(Combine_Mesh_vertexCount[count], Combine_Mesh_tangets[count], tangents, ref offset, invTranspose);
                    count++;
                }
            }

            offset=0;
            count = 0 ;
            //foreach( MeshInstance combine in combines )
            for(int i =0;i< combines.Length;i++)
            {

                if(Has_mesh[count] == 1){
                    Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_uv[count], uv, ref offset);
                }

                count++;
            }

            offset=0;
            count = 0 ;
            //foreach( MeshInstance combine in combines )
            for(int i =0;i< combines.Length;i++)
            {

                if(Has_mesh[count] == 1){
                    Copy(Combine_Mesh_vertexCount[count], Combine_Mesh_uv1[count], uv1, ref offset);
                }

                count++;
            }

            offset=0;
            count = 0 ;
            //foreach( MeshInstance combine in combines )
            for(int i =0;i< combines.Length;i++)
            {

                if(Has_mesh[count] == 1){
                    CopyColors(Combine_Mesh_vertexCount[count], Combine_Mesh_colors[count], colors, ref offset);
                }

                count++;
            }

            int triangleOffset=0;
            int vertexOffset=0;
            count = 0 ;
            //foreach( MeshInstance combine in combines )
            for(int j =0;j< combines.Length;j++)
            {

                if(Has_mesh[count] == 1)
                {
                    int[]  inputtriangles = Combine_Mesh_triangles[count];

                    for (int i=0;i<inputtriangles.Length;i++)
                    {
                        triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset;
                    }

                    triangleOffset += inputtriangles.Length;

                    vertexOffset += Combine_Mesh_vertexCount[count];
                    count++;
                }
            }

            //Mesh mesh = new Mesh();
            ControlCombineChildrenINfiniDyGrass.Meshy mesh = new ControlCombineChildrenINfiniDyGrass.Meshy();
            mesh.name = "Combined Mesh";
            mesh.vertices = vertices;
            mesh.normals = normals;
            mesh.colors = colors;
            mesh.uv = uv;
            mesh.uv1 = uv1;
            mesh.tangents = tangents;
            mesh.triangles = triangles;
            //thread_started = false;
            mesh.thread_ended = true;

            //Debug.Log ("ID = "+ID);

            return mesh;
        }
        public static Mesh Combine(MeshInstance[] combines, bool generateStrips)
        {
            int vertexCount = 0;

            int triangleCount = 0;

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

            {

                vertexCount += combine.mesh.vertexCount;

            }

            }

            // Precompute how many triangles we need

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

            {

                triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;

            }

            }

            Vector3[] vertices = new Vector3[vertexCount] ;

            Vector3[] normals = new Vector3[vertexCount] ;

            Vector4[] tangents = new Vector4[vertexCount] ;

            Vector2[] uv = new Vector2[vertexCount];

            Vector2[] uv1 = new Vector2[vertexCount];

            Color[] colors = new Color[vertexCount];

            int[] triangles = new int[triangleCount];

            int offset;

            offset=0;

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

                Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);

            }

            offset=0;

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

            {

                Matrix4x4 invTranspose = combine.transform;

                invTranspose = invTranspose.inverse.transpose;

                CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);

            }

            }

            offset=0;

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

            {

                Matrix4x4 invTranspose = combine.transform;

                invTranspose = invTranspose.inverse.transpose;

                CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);

            }

            }

            offset=0;

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

                Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);

            }

            offset=0;

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

                Copy(combine.mesh.vertexCount, combine.mesh.uv2, uv1, ref offset);

            }

            offset=0;

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

                CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset);

            }

            int triangleOffset=0;

            int vertexOffset=0;

            foreach( MeshInstance combine in combines )

            {

            if (combine.mesh)

            {

                int[]  inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);

                for (int i=0;i<inputtriangles.Length;i++)

                {

                    triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset;

                }

                triangleOffset += inputtriangles.Length;

                vertexOffset += combine.mesh.vertexCount;

            }

            }

            Mesh mesh = new Mesh();

            mesh.name = "Combined Mesh";

            mesh.vertices = vertices;

            mesh.normals = normals;

            mesh.colors = colors;

            mesh.uv = uv;

            mesh.uv2 = uv1;

            mesh.tangents = tangents;

            mesh.triangles = triangles;

            return mesh;
        }
	/// <summary>
	/// Combines the specified sm renderers.
	/// </summary>
	public void Combine(SkinnedMeshRenderer resultTarget, SkinnedMeshRenderer[] smRenderers)
	{
		if (smRenderers == null || smRenderers.Length == 0)
		{
			Debug.LogWarning("Combine skinned mesh: child renderers are null or empty");
			return;
		}

		//Debug.Log("Combine skinned mesh: child " + smRenderers.Length );

		// Temp values
		int modeDuplicate_boneOffset = 0; // for CombineMode.SharedBoneBindpose

		// Iterate all sub renderers
		for (int i = 0; i < smRenderers.Length; i++)
		{
			//Getting one by one
			SkinnedMeshRenderer smRenderer = smRenderers[i];

			// Making changes to the Skinned Renderer
			MeshInstance instance = new MeshInstance();

			// Setting the Mesh for the instance
			instance.mesh = smRenderer.sharedMesh;

			// Getting all materials
			Material[] sharedMaterials = smRenderer.sharedMaterials;
			for (int t = 0; t < sharedMaterials.Length; t++)
				materials.Add(sharedMaterials[t]);

			// 
			if (smRenderer != null && smRenderer.sharedMesh != null)
			{
				//instance.transform = Matrix4x4.identity; // myTransform /*transform.worldToLocalMatrix */ * smRenderer.transform.localToWorldMatrix;

				//Getting  subMesh
				for (int t = 0; t < smRenderer.sharedMesh.subMeshCount; t++)
				{
					instance.subMeshIndex = t;
					meshInstances.Add(instance);
				}

				//Copying Bones
				Transform[] smBones = smRenderer.bones;
				Matrix4x4[] smBindposes = smRenderer.sharedMesh.bindposes;
				BoneWeight[] smBoneweights = smRenderer.sharedMesh.boneWeights;

				switch (optimizeType)
				{
					case CombineMode.CalculateOverlappedBoneBindpose:
						{
							//Copying Bones
							for (int b = 0; b < smBones.Length; b++)
							{
								// New bone/bindpose combination
								SharedBoneBindpose sharedBoneBindpose = sharedGroups.Find(smBones[b], smBindposes[b]);
								if (sharedBoneBindpose != null)
									continue;

								// Create new bone/bindpose
								sharedBoneBindpose = sharedGroups.Create(smBones[b], smBindposes[b], bones.Count);

								//inserting bones in totalBones
								bones.Add(smBones[b]);
								//Recalculating BindPoses
								bindposes.Add(smBindposes[b]);
								//totalBindPoses[offset] = smRenderer.bones[x].worldToLocalMatrix * transform.localToWorldMatrix;
							}

							//RecalculateBoneWeights
							for (int bw = 0; bw < smBoneweights.Length; bw++)
							{
								//Just Copying and changing the Bones Indexes !!						
								boneWeights.Add(RecalculateBoneIndexes(smBoneweights[bw], sharedGroups, smBones, smBindposes));
							}
						}
						break;

					case CombineMode.SharedBoneBindpose:
						{
							//Copying Bones
							for (int b = 0; b < smBones.Length; b++)
							{
								// New bone/bindpose combination
								if (boneIndexLookup.ContainsKey(smBones[b]))
									continue;

								// Add to lookup
								boneIndexLookup.Add(smBones[b], bones.Count);

								//inserting bones in totalBones
								bones.Add(smBones[b]);
								//Recalculating BindPoses
								bindposes.Add(smBindposes[b]);
							}

							//RecalculateBoneWeights
							for (int bw = 0; bw < smBoneweights.Length; bw++)
							{
								//Just Copying and changing the Bones Indexes !!						
								boneWeights.Add(RecalculateBoneIndexes(smBoneweights[bw], boneIndexLookup, smBones, smBindposes));
							}
						}
						break;

					case CombineMode.DuplicateBoneBindpose:
						{
							// May want to modify this if the renderer shares bones as unnecessary bones will get added.
							foreach (BoneWeight bw in smBoneweights)
							{
								BoneWeight _bw = bw;

								_bw.boneIndex0 += modeDuplicate_boneOffset;
								_bw.boneIndex1 += modeDuplicate_boneOffset;
								_bw.boneIndex2 += modeDuplicate_boneOffset;
								_bw.boneIndex3 += modeDuplicate_boneOffset;

								boneWeights.Add(_bw);
							}
							modeDuplicate_boneOffset += smBones.Length;

							foreach (Transform bone in smBones)
								bones.Add(bone);

							for (int b = 0; b < smBones.Length; b++)
							{
								bindposes.Add(smBindposes[b]); // bones[b].worldToLocalMatrix * transform.localToWorldMatrix);
							}
						}
						break;
				}

				// Disabling current SkinnedMeshRenderer
				EndCombineChildRenderer(smRenderer);
			}
		}

		// Build final mesh
		Build(resultTarget);
	}
Exemple #40
0
        private IVertexRenderer<TexturedColouredVertex4> GetRendererFor(MeshInstance meshInstance)
        {
            IVertexRenderer<TexturedColouredVertex4> renderer;

            if (_vertexRenderers.TryGetValue(meshInstance.TriangleCount, out renderer))
            {
                return renderer;
            }

            renderer = _graphicsContext.CreateVertexRenderer<TexturedColouredVertex4>(meshInstance.TriangleCount * 3);

            _vertexRenderers[meshInstance.TriangleCount] = renderer;

            return renderer;
        }
    public static MeshData ColorCombine(MeshInstance[] combines, out bool success)
    {
        int length = combines.Length;
        int vertexCount = 0;
        int triangleCount = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                vertexCount += combines[combIndex].meshData.vertexCount;
            }
        }

        if(vertexCount > 65535)
        {
            //Debug.LogError("Combined mesh would have " + vertexCount + " vertices. Should not be more than 65535");
            success = false;
            return null;
        }

        // Precomputed how many triangles we need instead
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                triangleCount += combines[combIndex].meshData.triangles.Length;
            }
        }

        Vector3[] vertices = new Vector3[vertexCount];
        Vector3[] normals = new Vector3[vertexCount];
        Vector4[] tangents = new Vector4[vertexCount];
        Vector2[] uv = new Vector2[vertexCount];
        Vector2[] uv2 = new Vector2[vertexCount];
        Color[] colors = new Color[vertexCount];

        List<int> triangles = new List<int>();
        triangles.Capacity = triangleCount;

        int offset;

        offset = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
                Copy(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.vertices, vertices, ref offset, combines[combIndex].transform);
        }

        offset = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                Matrix4x4 invTranspose = combines[combIndex].transform;
                invTranspose = invTranspose.inverse.transpose;
                CopyNormal(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.normals, normals, ref offset, invTranspose);
            }

        }
        offset = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                Matrix4x4 invTranspose = combines[combIndex].transform;
                invTranspose = invTranspose.inverse.transpose;
                CopyTangents(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.tangents, tangents, ref offset, invTranspose);
            }

        }
        offset = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                Copy(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.uv, uv, ref offset, combines[combIndex].uv1Transform);
            }
        }

        offset = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                Copy(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.uv, uv2, ref offset, combines[combIndex].uv2Transform);
            }
        }

        offset = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
                CopyColors(combines[combIndex].meshData.vertexCount, combines[combIndex].meshData.colors, colors, ref offset, combines[combIndex].color);
        }

        int triangleOffset = 0;
        int vertexOffset = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {

                int[] inputtriangles = combines[combIndex].meshData.triangles;
                var inputVertices = combines[combIndex].meshData.vertices;
                int copiedTriangles = 0;
                for (int i = 0; i < inputtriangles.Length; i += 3)
                {
                    int vert0 = inputtriangles[i + 0];
                    int vert1 = inputtriangles[i + 1];
                    int vert2 = inputtriangles[i + 2];
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.Up) == HiddenFaces.Up)
                        && (inputVertices[vert0].y > topThreshold)
                        && (inputVertices[vert1].y > topThreshold)
                        && (inputVertices[vert2].y > topThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.Down) == HiddenFaces.Down)
                        && (inputVertices[vert0].y < -topThreshold)
                        && (inputVertices[vert1].y < -topThreshold)
                        && (inputVertices[vert2].y < -topThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.North) == HiddenFaces.North)
                        && (inputVertices[vert0].z > sideThreshold)
                        && (inputVertices[vert1].z > sideThreshold)
                        && (inputVertices[vert2].z > sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.South) == HiddenFaces.South)
                        && (inputVertices[vert0].z < -sideThreshold)
                        && (inputVertices[vert1].z < -sideThreshold)
                        && (inputVertices[vert2].z < -sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.East) == HiddenFaces.East)
                        && (inputVertices[vert0].x > sideThreshold)
                        && (inputVertices[vert1].x > sideThreshold)
                        && (inputVertices[vert2].x > sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.West) == HiddenFaces.West)
                        && (inputVertices[vert0].x < -sideThreshold)
                        && (inputVertices[vert1].x < -sideThreshold)
                        && (inputVertices[vert2].x < -sideThreshold))
                        continue;
                    triangles.Add(vert0 + vertexOffset);
                    triangles.Add(vert1 + vertexOffset);
                    triangles.Add(vert2 + vertexOffset);
                    copiedTriangles += 3;
                }
                triangleOffset += copiedTriangles;

                vertexOffset += combines[combIndex].meshData.vertexCount;
            }
        }
        success = true;
        return new MeshData(
            vertices: vertices,
            normals: normals,
            tangents: tangents,
            uv: uv,
            uv2: uv2,
            colors: colors,
            triangles: triangles.ToArray()
            );
    }
	public static Mesh Combine (MeshInstance[] combines, bool generateStrips)
	{
		int vertexCount = 0;
		int triangleCount = 0;
		int stripCount = 0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				vertexCount += combine.mesh.vertexCount;
				
				if (generateStrips)
				{
					int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length;
                   // int curStripCount = combine.mesh.GetTriangles(combine.subMeshIndex).Length
					if (curStripCount != 0)
					{
						if( stripCount != 0 )
						{
							if ((stripCount & 1) == 1 )
								stripCount += 3;
							else
								stripCount += 2;
						}
						stripCount += curStripCount;
					}
					else
					{
						generateStrips = false;
					}
				}
			}
		}

		if (!generateStrips)
		{
			foreach( MeshInstance combine in combines )
			{
				if (combine.mesh)
				{
					triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;
				}
			}
		}
		
		Vector3[] vertices = new Vector3[vertexCount] ;
		Vector3[] normals = new Vector3[vertexCount] ;
		Vector4[] tangents = new Vector4[vertexCount] ;
		Vector2[] uv = new Vector2[vertexCount];
		Vector2[] uv1 = new Vector2[vertexCount];
		int[] triangles = new int[triangleCount];
		int[] strip = new int[stripCount];
		
		int offset;
        System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
        sw.Start();
	
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);
		}

		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				Matrix4x4 invTranspose = combine.transform;
				invTranspose = invTranspose.inverse.transpose;
				CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);
			}
				
		}
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				Matrix4x4 invTranspose = combine.transform;
				invTranspose = invTranspose.inverse.transpose;
				CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);
			}
				
		}
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);
		}
		
		offset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				Copy(combine.mesh.vertexCount, combine.mesh.uv1, uv1, ref offset);
		}
		
		int triangleOffset=0;
		int stripOffset=0;
		int vertexOffset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				if (generateStrips)
				{
					int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex);
                    //int[] inputstrip = combine.mesh.GetTriangles(combine.subMeshIndex);
					if (stripOffset != 0)
					{
						if ((stripOffset & 1) == 1)
						{
							strip[stripOffset+0] = strip[stripOffset-1];
							strip[stripOffset+1] = inputstrip[0] + vertexOffset;
							strip[stripOffset+2] = inputstrip[0] + vertexOffset;
							stripOffset+=3;
						}
						else
						{
							strip[stripOffset+0] = strip[stripOffset-1];
							strip[stripOffset+1] = inputstrip[0] + vertexOffset;
							stripOffset+=2;
						}
					}
					
					for (int i=0;i<inputstrip.Length;i++)
					{
						strip[i+stripOffset] = inputstrip[i] + vertexOffset;
					}
					stripOffset += inputstrip.Length;
				}
				else
				{
					int[]  inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);
					for (int i=0;i<inputtriangles.Length;i++)
					{
						triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset;
					}
					triangleOffset += inputtriangles.Length;
				}
				
				vertexOffset += combine.mesh.vertexCount;
			}
		}
		Mesh mesh = new Mesh();
		mesh.name = "Combined Mesh";
		mesh.vertices = vertices;
		mesh.normals = normals;
		mesh.tangents = tangents;
		mesh.uv = uv;
		mesh.uv1 = uv1;
		if (generateStrips)
			mesh.SetTriangleStrip(strip, 0);
		else
			mesh.triangles = triangles;
        sw.Stop();
        Mogo.Util.LoggerHelper.Debug("Combine Mesh cost: " + sw.ElapsedMilliseconds);
        return mesh;
	}
		internal static Mesh InternalCombineVertices(MeshInstance[] meshes, string meshName){}
        public static Mesh[] Combine(MeshInstance[] combines)
        {
            int vertexCount = 0;
            int triangleCount = 0;

            for (int i = 0; i < combines.Length; i++) {
                if (combines [i].mesh != null) {
                    vertexCount += combines [i].mesh.vertexCount;
                    triangleCount += combines [i].mesh.GetTriangles(combines [i].subMeshIndex).Length;
                }
            }

            int indexOffset = 0;
            int numOfSplits = Mathf.CeilToInt(vertexCount / 60000.0f);
            int vertsPerSplit = vertexCount / numOfSplits;
            List<Mesh> meshSplits = new List<Mesh>();

            for (int i = 1; i <= numOfSplits; i++) {
                List<Vector3> vertices = new List<Vector3>(vertsPerSplit);
                List<Vector3> normals = new List<Vector3>(vertsPerSplit);
                List<Vector4> tangents = new List<Vector4>(vertsPerSplit);
                List<Vector2> uv = new List<Vector2>(vertsPerSplit);
                List<Vector2> uv1 = new List<Vector2>(vertsPerSplit);
                List<Vector2> uv2 = new List<Vector2>(vertsPerSplit);
                List<Color> colors = new List<Color>(vertsPerSplit);

                List<int> triangles = new List<int>(triangleCount / numOfSplits);

                int vertexOffset = 0;

                while (indexOffset < combines.Length && vertexOffset <= vertsPerSplit) {
                    if (combines [indexOffset].mesh != null) {
                        Copy(combines [indexOffset].mesh.vertices, vertices, combines [indexOffset].transform);

                        Matrix4x4 invTranspose = combines [indexOffset].transform;
                        invTranspose = invTranspose.inverse.transpose;
                        CopyNormal(combines [indexOffset].mesh.normals, normals, invTranspose);

                        CopyTangents(combines [indexOffset].mesh.tangents, tangents, invTranspose);

                        Copy(combines [indexOffset].mesh.uv, uv);

                        Copy(combines [indexOffset].mesh.uv1, uv1);

                        Copy(combines [indexOffset].mesh.uv2, uv2);
                        if (combines [indexOffset].mesh.colors.Length == combines [indexOffset].mesh.vertexCount) {
                            CopyColors(combines [indexOffset].mesh.colors, colors);
                        } else {
                            Color[] newColors = new Color[combines [indexOffset].mesh.vertexCount];
                            for (int x = 0; x < newColors .Length; x++) {
                                newColors [x] = Color.white;
                            }
                            CopyColors(newColors, colors);
                        }

                        CopyTriangles(combines [indexOffset].mesh.GetTriangles(combines [indexOffset].subMeshIndex), triangles, vertexOffset);

                        vertexOffset += combines [indexOffset].mesh.vertexCount;
                    }

                    indexOffset++;
                }

                Mesh mesh = new Mesh();
                mesh.name = "Combined Mesh";
                mesh.vertices = vertices.ToArray();
                mesh.normals = normals.ToArray();
                mesh.colors = colors.ToArray();
                mesh.uv = uv.ToArray();
                mesh.uv1 = uv1.ToArray();
                mesh.uv2 = uv2.ToArray();
                mesh.tangents = tangents.ToArray();

                mesh.triangles = triangles.ToArray();

                meshSplits.Add(mesh);
            }

            return meshSplits.ToArray();
        }
	public static Mesh Combine (MeshInstance[] combines, bool bakeGroundLightingGrass, bool bakeGroundLightingFoliage, float randomBrightness, float randomPulse, float randomBending, float randomFluttering, Color HealthyColor, Color DryColor, float NoiseSpread, bool bakeScale, bool simplyCombine, float NoiseSpreadFoliage, bool createUniqueUV2, bool useUV4
)
	{
		int vertexCount = 0;
		int triangleCount = 0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				vertexCount += combine.mesh.vertexCount;
				triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;
			}
		}

		Vector3[] vertices = new Vector3[vertexCount] ;
		Vector3[] normals = new Vector3[vertexCount] ;
		Vector4[] tangents = new Vector4[vertexCount] ;
		Vector2[] uv = new Vector2[vertexCount];
//		
		Vector2[] uv1 = new Vector2[vertexCount];
		Color[] colors = new Color[vertexCount];
//
		Vector2[] uv4 = new Vector2[vertexCount];
		
		int[] triangles = new int[triangleCount];
		int offset;
		offset=0;

		bool copyUV4 = false;

		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);
		}
		offset=0;

		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				Matrix4x4 invTranspose = combine.transform;
				invTranspose = invTranspose.inverse.transpose;
				
				//if (bakeGroundLightingGrassTrans) {
				//	CopyNormalGroundTrans (combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose, combine.groundNormal);
				//}
				if (bakeGroundLightingGrass) {
					CopyNormalGround (combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose, combine.groundNormal);
				}
				//else if (!bakeGroundLightingGrassTrans) {
				else {
					CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);
				}
			}
		}
		offset=0;

		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				Matrix4x4 invTranspose = combine.transform;
				invTranspose = invTranspose.inverse.transpose;
				CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);
			}
				
		}
		offset=0;

		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
				Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);
		}
		offset=0;
		
		// only needed when using the foliage shader ground lighting version
		if (bakeGroundLightingFoliage) {
			foreach( MeshInstance combine in combines )
			{
				if (combine.mesh)
					Copy_uv1(combine.mesh.vertexCount, combine.mesh.uv, uv1, ref offset, new Vector2(combine.groundNormal.x, combine.groundNormal.z));
			}
			offset=0;
		}

		// Copy uv4 
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh.uv4 != null && useUV4)
			{
				//Debug.Log("UV4 found");
				copyUV4 = true;
				Copy_uv4(combine.mesh.vertexCount, combine.mesh.uv4, uv4, ref offset, combine.scale, bakeScale, combine.pivot, NoiseSpreadFoliage, randomBending);
			}
		}
		offset=0;

		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh) {
				// either add healthy and dry colors (grass shader)
				if (bakeGroundLightingGrass) {
					CopyColors_grass(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset, HealthyColor, DryColor, NoiseSpread, combine.pivot );
				}
				// or simply add random color to create more variety (r,a and b) and bake scale
				else {
					//CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset, new Color (Random.Range(0.0f, randomPulse), Random.Range(-randomFluttering, randomFluttering), Random.Range(-randomBending, randomBending), Random.Range(randomBrightness, -randomBrightness)), combine.scale, bakeScale);
					CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset, combine.scale, bakeScale, combine.pivot, NoiseSpreadFoliage, randomPulse, randomFluttering, randomBrightness, randomBending, copyUV4);
				}
			}
		}
		

		int triangleOffset=0;
		int vertexOffset=0;
		foreach( MeshInstance combine in combines )
		{
			if (combine.mesh)
			{
				int[]  inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);
				for (int i=0;i<inputtriangles.Length;i++)
				{
					triangles[i+triangleOffset] = inputtriangles[i] + vertexOffset;
				}
				triangleOffset += inputtriangles.Length;
				vertexOffset += combine.mesh.vertexCount;
				// Clean up
				inputtriangles = null;
			}
		}
		
		Mesh mesh = new Mesh();
		mesh.name = "Combined Mesh";
		mesh.vertices = vertices;
		mesh.normals = normals;
		mesh.colors = colors;
		mesh.uv = uv;
		// only needed for foliage shader, skip it on grass and plants using the regular shader
		if (bakeGroundLightingFoliage) {
			mesh.uv2 = uv1;
		}

		if (copyUV4) {
			mesh.uv4 = uv4;
		}

		mesh.tangents = tangents;
		mesh.triangles = triangles;
		mesh.Optimize();

		#if UNITY_EDITOR
			if(createUniqueUV2 && !bakeGroundLightingFoliage) {
				Unwrapping.GenerateSecondaryUVSet(mesh);
			}
		#endif



		// Clean up
		vertices = null;
		normals = null;
		tangents = null;
		uv = null;
		uv1 = null;
		colors = null;
		triangles = null;

		return mesh;
	}
    private static int getIndex(Dictionary<int, int> indexTranslation, MeshInstance meshInstance, int inputVert, List<Vector3> vertices, List<Vector3> normals, List<Vector4> tangents, List<Vector2> uvs, List<Vector2> uv2s, List<Vector2> uv3s, List<Color> colors, Vector3[] inputVertices, Vector3[] inputNormals, Vector4[] inputTangents, Vector2[] inputUVs, Color[] inputColors, Vector2? uv2Force, Vector2? uv3Force)
    {
        int newVert;
        if (indexTranslation.ContainsKey(inputVert))
        {
            newVert = indexTranslation[inputVert];
        }
        else
        {
            newVert = vertices.Count;
            indexTranslation[inputVert] = newVert;
            vertices.Add(meshInstance.transform.MultiplyPoint(inputVertices[inputVert]));

            Matrix4x4 invTranspose = meshInstance.transform;
            invTranspose = invTranspose.inverse.transpose;
            normals.Add(invTranspose.MultiplyVector(inputNormals[inputVert]).normalized);
            Vector4 p4 = inputTangents[inputVert];
            Vector3 p = new Vector3(p4.x, p4.y, p4.z);
            p = invTranspose.MultiplyVector(p).normalized;
            tangents.Add(invTranspose.MultiplyVector(new Vector4(p.x, p.y, p.z, p4.w)));
            uvs.Add(meshInstance.uv1Transform.MultiplyPoint(inputUVs[inputVert]));
            if (!uv2Force.HasValue)
                uv2s.Add(meshInstance.uv2Transform.MultiplyPoint(inputUVs[inputVert]));
            else
                uv2s.Add(uv2Force.Value);

            if (!uv3Force.HasValue)
                uv3s.Add(meshInstance.uv3Transform.MultiplyPoint(inputUVs[inputVert]));
            else
                uv3s.Add(uv3Force.Value);
            if (inputColors.Length > 0)
                colors.Add(meshInstance.color * inputColors[inputVert]);
            else
                colors.Add(meshInstance.color);
        }
        return newVert;
    }
Exemple #47
0
        /// <summary>
        /// Event raised by the planet when a new surface is generated.
        /// If enabled, adds SurfaceObjects component to the Surface and populates it with objects
        /// </summary>
        public void OnSurfaceGenerated(Surface surface)
        {
            for(int f = 0; f < foliageTypes.Length; f++) {
            if(surface.lodLevel == foliageTypes[f].lodLevel) {
                // create new list
                MeshInstanceList mil = new MeshInstanceList();
                mil.meshInstances = new List<MeshInstance>();

                // save surface reference and listen for its destruction
                mil.surface = surface;
                surface.SurfaceDestroyed += SurfaceDestroyed;

                // get mesh
                Vector3[] vertices = surface.mesh.vertices;
                Vector3[] normals = surface.mesh.normals;
                Color[] colors = surface.mesh.colors;

                Vector3 right = Vector3.zero; //, perpendicular = Vector3.one, normalized = Vector3.zero;
                //float vertexDistance = 0f;

                for(int i = 0; i < vertices.Length; i++) {
                    if(i + 1 < vertices.Length) {
                        right = vertices[i] - vertices[i+1];
                        //vertexDistance = right.magnitude;
                        right.Normalize();
                    }

                    if(colors[i].r >= foliageTypes[f].minHeight && colors[i].r <= foliageTypes[f].maxHeight &&
                       colors[i].g >= foliageTypes[f].minPolarity && colors[i].g <= foliageTypes[f].maxPolarity &&
                       colors[i].b >= foliageTypes[f].minSlope && colors[i].b <= foliageTypes[f].maxSlope ) {
                        float terrainValue = terrainModule.module.GetValue(vertices[i].normalized);
                        if(terrainValue >= foliageTypes[f].minNoiseValue && terrainValue <= foliageTypes[f].maxNoiseValue) {
                            MeshInstance newInstance = new MeshInstance();

                            Vector3 vertex = planet.transform.TransformPoint(vertices[i]);
                            Vector3 normal = planet.transform.TransformDirection(normals[i]);

                            /*if(foliageTypes[f].positionVariation != Vector3.zero) {
                                normalized = vertices[i].normalized;
                                perpendicular = Vector3.Cross(right, normalized);
                                newInstance.position += right * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.x, foliageTypes[f].positionVariation.x);
                                newInstance.position += normalized * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.y, foliageTypes[f].positionVariation.y);
                                newInstance.position += perpendicular * vertexDistance * Random.Range(-foliageTypes[f].positionVariation.z, foliageTypes[f].positionVariation.z);
                            }*/

                            Quaternion adjustedRotation;
                            if(foliageTypes[f].useGroundNormalAsUp)
                                adjustedRotation = Quaternion.LookRotation(normal);
                            else
                                adjustedRotation = Quaternion.LookRotation(vertex.normalized);
                            adjustedRotation *= Quaternion.Euler(foliageTypes[f].rotation);
                            adjustedRotation *= Quaternion.Euler(new Vector3(Random.Range(-foliageTypes[f].rotationVariation.x, foliageTypes[f].rotationVariation.x),
                                                                             Random.Range(-foliageTypes[f].rotationVariation.y, foliageTypes[f].rotationVariation.y),
                                                                             Random.Range(-foliageTypes[f].rotationVariation.z, foliageTypes[f].rotationVariation.z)));

                            Vector3 adjustedScale = foliageTypes[f].scale * (1f + foliageTypes[f].scaleVariation * Random.Range(0f, 1f));

                            newInstance.position = vertex;
                            newInstance.scale = adjustedScale;

                            newInstance.matrix = new Matrix4x4();
                            newInstance.matrix.SetTRS(newInstance.position, adjustedRotation, adjustedScale);

                            newInstance.mesh = foliageTypes[f].mesh;
                            newInstance.materials = foliageTypes[f].materials;
                            newInstance.layer = foliageTypes[f].meshLayer;
                            newInstance.castShadows = foliageTypes[f].castShadows;
                            newInstance.receiveShadows = foliageTypes[f].receiveShadows;

                            mil.meshInstances.Add(newInstance);
                        }
                    }
                }

                // add list to other lists
                foliageTypes[f].meshLists.Add(mil);
            }
            }
        }
    public static CPUMesh ColorCombine(MeshInstance[] combines, out bool success, bool topLayer = false, CPUMesh sourceMesh = null)
    {
        int length = combines.Length;
        int vertexCount = 0;
        int triangleCount = 0;
        int maxVertices = 0;
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                int count = combines[combIndex].meshData.vertexCount;
                vertexCount += count;
                if (maxVertices < count)
                    maxVertices = count;
            }
        }
        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                triangleCount += combines[combIndex].meshData.triangles.Length;
            }
        }

        List<Vector3> vertices = new List<Vector3>(vertexCount);
        List<Vector3> normals = new List<Vector3>(vertexCount);
        List<Vector4> tangents = new List<Vector4>(vertexCount);
        List<Vector2> uvs = new List<Vector2>(vertexCount);
        List<Vector2> uv2s = new List<Vector2>(vertexCount);
        List<Vector2> uv3s = new List<Vector2>(vertexCount);
        List<Color> colors = new List<Color>(vertexCount);
        List<int> triangles = new List<int>(triangleCount);

        if (
            sourceMesh != null
            && sourceMesh.vertices != null
            && sourceMesh.vertices.Length != 0
            && sourceMesh.triangles != null
            && sourceMesh.triangles.Length != 0)
        {
            vertices.AddRange(sourceMesh.vertices);
            if (sourceMesh.normals != null)
                normals.AddRange(sourceMesh.normals);
            else
                normals.AddRange(new Vector3[sourceMesh.vertices.Length]);

            if (sourceMesh.tangents != null)
                tangents.AddRange(sourceMesh.tangents);
            else
                tangents.AddRange(new Vector4[sourceMesh.vertices.Length]);

            if (sourceMesh.uv != null)
                uvs.AddRange(sourceMesh.uv);
            else
                uvs.AddRange(new Vector2[sourceMesh.vertices.Length]);

            if (sourceMesh.uv2 != null)
                uv2s.AddRange(sourceMesh.uv2);
            else
                uv2s.AddRange(new Vector2[sourceMesh.vertices.Length]);

            if (sourceMesh.uv3 != null)
                uv3s.AddRange(sourceMesh.uv3);
            else
                uv3s.AddRange(new Vector2[sourceMesh.vertices.Length]);

            if (sourceMesh.colors != null)
                colors.AddRange(sourceMesh.colors);
            else
                colors.AddRange(new Color[sourceMesh.vertices.Length]);

            triangles.AddRange(sourceMesh.triangles);
        }

        Dictionary<int, int> indexTranslation = new Dictionary<int, int>(maxVertices);

        for (int combIndex = 0; combIndex < length; combIndex++)
        {
            if (combines[combIndex].meshData != null)
            {
                int[] inputtriangles = combines[combIndex].meshData.triangles;
                var inputVertices = combines[combIndex].meshData.vertices;
                var inputNormals = combines[combIndex].meshData.normals;
                var inputUVs = combines[combIndex].meshData.uv;
                var inputColors = combines[combIndex].meshData.colors;
                var inputTangents = combines[combIndex].meshData.tangents;
                for (int i = 0; i < inputtriangles.Length; i += 3)
                {
                    int vert0 = inputtriangles[i + 0];
                    int vert1 = inputtriangles[i + 1];
                    int vert2 = inputtriangles[i + 2];
                    if (topLayer)
                    {
                        if (!(((combines[combIndex].hiddenFaces & HiddenFaces.Up) == HiddenFaces.Up)
                            && (inputVertices[vert0].y > topThreshold)
                            && (inputVertices[vert1].y > topThreshold)
                            && (inputVertices[vert2].y > topThreshold)))
                            continue;
                    }
                    else
                    {
                        if (((combines[combIndex].hiddenFaces & HiddenFaces.Up) == HiddenFaces.Up)
                            && (inputVertices[vert0].y > topThreshold)
                            && (inputVertices[vert1].y > topThreshold)
                            && (inputVertices[vert2].y > topThreshold))
                            continue;
                    }
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.Down) == HiddenFaces.Down)
                        && (inputVertices[vert0].y < -topThreshold)
                        && (inputVertices[vert1].y < -topThreshold)
                        && (inputVertices[vert2].y < -topThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.North) == HiddenFaces.North)
                        && (inputVertices[vert0].z > sideThreshold)
                        && (inputVertices[vert1].z > sideThreshold)
                        && (inputVertices[vert2].z > sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.South) == HiddenFaces.South)
                        && (inputVertices[vert0].z < -sideThreshold)
                        && (inputVertices[vert1].z < -sideThreshold)
                        && (inputVertices[vert2].z < -sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.East) == HiddenFaces.East)
                        && (inputVertices[vert0].x > sideThreshold)
                        && (inputVertices[vert1].x > sideThreshold)
                        && (inputVertices[vert2].x > sideThreshold))
                        continue;
                    if (((combines[combIndex].hiddenFaces & HiddenFaces.West) == HiddenFaces.West)
                        && (inputVertices[vert0].x < -sideThreshold)
                        && (inputVertices[vert1].x < -sideThreshold)
                        && (inputVertices[vert2].x < -sideThreshold))
                        continue;

                    int newVert0 = getIndex(indexTranslation, combines[combIndex], vert0, vertices, normals, tangents, uvs, uv2s, uv3s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors, combines[combIndex].uv2Force, combines[combIndex].uv3Force);
                    int newVert1 = getIndex(indexTranslation, combines[combIndex], vert1, vertices, normals, tangents, uvs, uv2s, uv3s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors, combines[combIndex].uv2Force, combines[combIndex].uv3Force);
                    int newVert2 = getIndex(indexTranslation, combines[combIndex], vert2, vertices, normals, tangents, uvs, uv2s, uv3s, colors, inputVertices, inputNormals, inputTangents, inputUVs, inputColors, combines[combIndex].uv2Force, combines[combIndex].uv3Force);

                    if (newVert0 > 65531 || newVert1 > 65531 || newVert2 > 65531)
                        goto failure;

                    triangles.Add(newVert0);
                    triangles.Add(newVert1);
                    triangles.Add(newVert2);
                }
            }
            indexTranslation.Clear();
        }
        success = true;
        return new CPUMesh(
            vertices: vertices.ToArray(),
            normals: normals.ToArray(),
            tangents: tangents.ToArray(),
            uv: uvs.ToArray(),
            uv2: uv2s.ToArray(),
            uv3: uv3s.ToArray(),
            colors: colors.ToArray(),
            triangles: triangles.ToArray()
            );
        failure:
        success = false;
        return new CPUMesh(
            vertices: vertices.ToArray(),
            normals: normals.ToArray(),
            tangents: tangents.ToArray(),
            uv: uvs.ToArray(),
            uv2: uv2s.ToArray(),
            uv3: uv3s.ToArray(),
            colors: colors.ToArray(),
            triangles: triangles.ToArray()
            );
    }
    public static Mesh Combine(MeshInstance[] combines, bool generateStrips) {
        int vertexCount = 0;
        int triangleCount = 0;
        int stripCount = 0;
        foreach (MeshInstance combine in combines) {
            if (combine.mesh) {
                vertexCount += combine.mesh.vertexCount;

                if (generateStrips) {
                    // SUBOPTIMAL FOR PERFORMANCE
                    int curStripCount = combine.mesh.GetTriangleStrip(combine.subMeshIndex).Length;
                    if (curStripCount != 0) {
                        if (stripCount != 0) {
                            if ((stripCount & 1) == 1) {
                                stripCount += 3;
                            } else {
                                stripCount += 2;
                            }
                        }
                        stripCount += curStripCount;
                    } else {
                        generateStrips = false;
                    }
                }
            }
        }

        // Precomputed how many triangles we need instead
        if (!generateStrips) {
            foreach (MeshInstance combine in combines) {
                if (combine.mesh) {
                    triangleCount += combine.mesh.GetTriangles(combine.subMeshIndex).Length;
                }
            }
        }

        var vertices = new Vector3[vertexCount];
        var normals = new Vector3[vertexCount];
        var tangents = new Vector4[vertexCount];
        var uv = new Vector2[vertexCount];
        var uv1 = new Vector2[vertexCount];
        var colors = new Color[vertexCount];

        var triangles = new int[triangleCount];
        var strip = new int[stripCount];

        int offset;
        int offsetUv;
        float sizeUv;
        int row;

        offset = 0;
        foreach (MeshInstance combine in combines) {
            if (combine.mesh) {
                Copy(combine.mesh.vertexCount, combine.mesh.vertices, vertices, ref offset, combine.transform);
            }
        }

        offset = 0;
        foreach (MeshInstance combine in combines) {
            if (combine.mesh) {
                Matrix4x4 invTranspose = combine.transform;
                invTranspose = invTranspose.inverse.transpose;
                CopyNormal(combine.mesh.vertexCount, combine.mesh.normals, normals, ref offset, invTranspose);
            }
        }
        offset = 0;
        foreach (MeshInstance combine in combines) {
            if (combine.mesh) {
                Matrix4x4 invTranspose = combine.transform;
                invTranspose = invTranspose.inverse.transpose;
                CopyTangents(combine.mesh.vertexCount, combine.mesh.tangents, tangents, ref offset, invTranspose);
            }
        }
        offset = 0;
        foreach (MeshInstance combine in combines) {
            if (combine.mesh) {
                Copy(combine.mesh.vertexCount, combine.mesh.uv, uv, ref offset);
            }
        }

        offset = 0;
        offsetUv = 0;
        row = (int) Mathf.Ceil(Mathf.Sqrt(combines.Length));
        sizeUv = (float) 1 / row;
        foreach (MeshInstance combine in combines) {
            if (combine.mesh) {
                CopyUv(combine.mesh.vertexCount, combine.mesh.uv1, uv1, sizeUv, row, ref offset, ref offsetUv);
            }
        }

        offset = 0;
        foreach (MeshInstance combine in combines) {
            if (combine.mesh) {
                CopyColors(combine.mesh.vertexCount, combine.mesh.colors, colors, ref offset);
            }
        }

        int triangleOffset = 0;
        int stripOffset = 0;
        int vertexOffset = 0;
        foreach (MeshInstance combine in combines) {
            if (combine.mesh) {
                if (generateStrips) {
                    int[] inputstrip = combine.mesh.GetTriangleStrip(combine.subMeshIndex);
                    if (stripOffset != 0) {
                        if ((stripOffset & 1) == 1) {
                            strip[stripOffset + 0] = strip[stripOffset - 1];
                            strip[stripOffset + 1] = inputstrip[0] + vertexOffset;
                            strip[stripOffset + 2] = inputstrip[0] + vertexOffset;
                            stripOffset += 3;
                        } else {
                            strip[stripOffset + 0] = strip[stripOffset - 1];
                            strip[stripOffset + 1] = inputstrip[0] + vertexOffset;
                            stripOffset += 2;
                        }
                    }

                    for (int i = 0; i < inputstrip.Length; i++) {
                        strip[i + stripOffset] = inputstrip[i] + vertexOffset;
                    }
                    stripOffset += inputstrip.Length;
                } else {
                    int[] inputtriangles = combine.mesh.GetTriangles(combine.subMeshIndex);
                    for (int i = 0; i < inputtriangles.Length; i++) {
                        triangles[i + triangleOffset] = inputtriangles[i] + vertexOffset;
                    }
                    triangleOffset += inputtriangles.Length;
                }

                vertexOffset += combine.mesh.vertexCount;
            }
        }

        var mesh = new Mesh();
        mesh.name = "Combined Mesh";
        mesh.vertices = vertices;
        mesh.normals = normals;
        mesh.colors = colors;
        mesh.uv = uv;
        mesh.uv1 = uv1;
        mesh.tangents = tangents;
        if (generateStrips) {
            mesh.SetTriangleStrip(strip, 0);
        } else {
            mesh.triangles = triangles;
        }

        return mesh;
    }