public virtual void ResetMultimesh()
    {
        if (mesh == null)
        {
            Multimesh = null;
            return;
        }

        Multimesh = new MultiMesh();
        Multimesh.TransformFormat = MultiMesh.TransformFormatEnum.Transform3d;
        Multimesh.ColorFormat     = MultiMesh.ColorFormatEnum.Float;
        Multimesh.Mesh            = mesh;
        Multimesh.InstanceCount   = numParticles;
    }
        private void Reset()
        {
            Mesh usedMesh = mesh;

            if (usedMesh == null)
            {
                SurfaceTool st = new SurfaceTool();

                st.Begin(Mesh.PrimitiveType.Triangles);

                switch (drawMode)
                {
                case DrawMode.SingleTriangle:
                {
                    st.AddUv(new Vector2(0, 0));
                    st.AddVertex(new Vector3(-.5f, -.5f, 0));

                    st.AddUv(new Vector2(0, 2));
                    st.AddVertex(new Vector3(-.5f, 1.5f, 0));

                    st.AddUv(new Vector2(2, 0));
                    st.AddVertex(new Vector3(1.5f, -.5f, 0));
                    break;
                }

                case DrawMode.Quad:
                {
                    st.AddUv(new Vector2(0, 0));
                    st.AddVertex(new Vector3(-.5f, -.5f, 0));

                    st.AddUv(new Vector2(0, 1));
                    st.AddVertex(new Vector3(-.5f, .5f, 0));

                    st.AddUv(new Vector2(1, 0));
                    st.AddVertex(new Vector3(.5f, .51f, 0));

                    st.AddUv(new Vector2(1, 0));
                    st.AddVertex(new Vector3(.5f, -.5f, 0));

                    st.AddUv(new Vector2(0, 1));
                    st.AddVertex(new Vector3(-.5f, .5f, 0));

                    st.AddUv(new Vector2(1, 1));
                    st.AddVertex(new Vector3(.5f, .5f, 0));
                    break;
                }
                }

                //st.SetMaterial(particleSystem.testMaterial);
                st.Index();

                usedMesh = st.Commit();
            }

            multimesh = new MultiMesh();
            multimesh.TransformFormat = MultiMesh.TransformFormatEnum.Transform2d;
            multimesh.ColorFormat     = MultiMesh.ColorFormatEnum.Float;
            //multimesh.CustomDataFormat = MultiMesh.CustomDataFormatEnum.Float;
            multimesh.Mesh          = usedMesh;
            multimesh.InstanceCount = particleSystem.maxParticles;
        }
Example #3
0
    public override void _Ready()
    {
        base._Ready();


        var mesh    = GD.Load <Mesh>("res://asset/fish/Fish1.obj");
        var shader  = GD.Load <Shader>("res://asset/fish/fish1.shader");
        var diffuse = GD.Load <Texture>("res://asset/fish/Fish1-diffuse_base.png");

        shader.SetDefaultTextureParam("texture_albedo", diffuse);


        var mm = new MultiMesh();

        mm.TransformFormat  = MultiMesh.TransformFormatEnum.Transform3d;
        mm.ColorFormat      = MultiMesh.ColorFormatEnum.None;
        mm.CustomDataFormat = MultiMesh.CustomDataFormatEnum.None;


        this.Multimesh = new MultiMesh();
        this.Multimesh.TransformFormat  = MultiMesh.TransformFormatEnum.Transform3d;
        this.Multimesh.CustomDataFormat = MultiMesh.CustomDataFormatEnum.Float;
        this.Multimesh.Mesh             = mesh;
        //set shader
        {
            var shadMat = new ShaderMaterial();
            shadMat.Shader = shader;
            shadMat.SetShaderParam("texture_albedo", diffuse);
            this.MaterialOverride = shadMat;
        }
        this.Multimesh.InstanceCount = 10000;          //need to do this after setting the TransformFormat
        //mm.InstanceCount = 1000;
        //mm.VisibleInstanceCount = -1;


        //set initial placement
        var visibleCount = this.Multimesh.VisibleInstanceCount;

        if (visibleCount == -1)
        {
            visibleCount = this.Multimesh.InstanceCount;
        }

        //this vector3 array is actually a transform array (4 vector 3's)
        xforms = this.Multimesh.TransformArray;
        //so lets cast it into that!
        var spanV3 = new Span <Vector3>(xforms);
        var spanXf = MemoryMarshal.Cast <Vector3, Transform>(spanV3);


        //put all the fish into a grid
        {
            var seperationDistance = 5;
            var dim = Math.Pow(visibleCount, 1.0 / 3);
            GD.Print($"visibleCount={visibleCount}, xformsLen={xforms.Length}, dim={dim}");
            var i = 0;
            for (var x = 0; x < dim; x++)
            {
                for (var z = 0; z < dim; z++)
                {
                    for (var y = 0; y < dim; y++)
                    {
                        if (i >= visibleCount)
                        {
                            break;                             //need this because of rounding with our dim variable.
                        }
                        var loc = new Vector3((x * seperationDistance), y * seperationDistance, z * seperationDistance);
                        spanXf[i].origin = loc;                         //loc offset 3 is the position in a transform.  we could assign directly to array like this: //xforms[(i * 4) + 3] = loc;
                        //this.Multimesh.SetInstanceTransform(i, new Transform(Basis.Identity, loc)); //instead of updating 1 at a time, we update all after the loop is done.
                        i++;
                    }
                }
            }
        }
        this.Multimesh.TransformArray = xforms;
    }
Example #4
0
    public static void Read(Node node, Stream fs, out List <Tuple <SpatialMaterial, Texture[], float> > animat)
    {
        var zip      = new ZipFile(fs);
        var zonefile = zip.GetInputStream(zip.GetEntry("zone.oez"));
        var reader   = new BinaryReader(zonefile);

        var nummats   = reader.ReadInt32();
        var materials = new Dictionary <int, SpatialMaterial>();
        var hidden    = new Dictionary <int, bool>();

        animat = new List <Tuple <SpatialMaterial, Texture[], float> >();
        for (var i = 0; i < nummats; ++i)
        {
            var flags    = reader.ReadUInt32();
            var param    = reader.ReadUInt32();
            var numtex   = reader.ReadUInt32();
            var textures = new Texture[numtex];
            for (var j = 0; j < numtex; ++j)
            {
                var fn    = reader.ReadString();
                var entry = zip.GetEntry(fn);
                textures[j] = TextureLoader.Load(zip.GetInputStream(entry), (int)entry.Size, flags != 1);
            }
            hidden[i] = flags == 4;
            var mat = materials[i] = new SpatialMaterial();
            if (numtex > 1)
            {
                animat.Add(new Tuple <SpatialMaterial, Texture[], float>(mat, textures, param));
            }
            else if (numtex == 1)
            {
                mat.AlbedoTexture = textures[0];
            }
            if (flags == 1)
            {
                mat.ParamsUseAlphaScissor = true;
            }
            else if (flags != 0)
            {
                mat.FlagsTransparent = true;
            }
        }

        var objects = new List <ArrayMesh>();
        var colobjs = new List <ArrayMesh>();
        var numobjs = reader.ReadUInt32();

        WriteLine($"Num objs: {numobjs}");
        for (var i = 0; i < numobjs; ++i)
        {
            var obj    = new ArrayMesh();
            var colobj = new ArrayMesh();
            objects.Add(obj);
            colobjs.Add(colobj);
            var matoffs = new List <int>();

            var nummeshes = reader.ReadUInt32();
            WriteLine($"Num meshes: {nummeshes}");
            var surfid       = 0;
            var hasCollision = false;
            for (var j = 0; j < nummeshes; ++j)
            {
                var matid      = reader.ReadInt32();
                var collidable = reader.ReadUInt32() == 1;
                var numvert    = reader.ReadInt32();
                var arrays     = new object[ArrayMesh.ARRAY_MAX];
                arrays[ArrayMesh.ARRAY_VERTEX] = Enumerable.Range(0, numvert).Select(_ => reader.ReadVector3()).ToArray();
                arrays[ArrayMesh.ARRAY_NORMAL] = Enumerable.Range(0, numvert).Select(_ => reader.ReadVector3()).ToArray();
                arrays[ArrayMesh.ARRAY_TEX_UV] = Enumerable.Range(0, numvert).Select(_ => reader.ReadVector2()).ToArray();
                var numpoly = reader.ReadInt32();
                var ind     = Enumerable.Range(0, numpoly * 3).Select(_ => (int)reader.ReadUInt32()).ToArray();
                arrays[ArrayMesh.ARRAY_INDEX] = ind;

                if (collidable)
                {
                    colobj.AddSurfaceFromArrays(VisualServer.PRIMITIVE_TRIANGLES, arrays);
                    hasCollision = true;
                }

                if (hidden[matid])
                {
                    continue;
                }

                obj.AddSurfaceFromArrays(VisualServer.PRIMITIVE_TRIANGLES, arrays);
                obj.SurfaceSetMaterial(surfid++, materials[matid]);
            }

            if (!hasCollision)
            {
                colobjs[i] = null;
            }
        }
        WriteLine("Building base meshinstance");

        var mi = new MeshInstance {
            Mesh = objects[0]
        };

        node.AddChild(mi);

        if (colobjs[0] != null)
        {
            var cmi = new MeshInstance {
                Mesh = colobjs[0]
            };
            cmi.CreateTrimeshCollision();
            var body = cmi.GetChild(0);
            cmi.RemoveChild(body);
            node.AddChild(body);
        }

        WriteLine("Adding placeables");

        var oset = new List <Transform> [objects.Count - 1];

        for (var i = 0; i < oset.Length; ++i)
        {
            oset[i] = new List <Transform>();
        }
        var numplace = reader.ReadUInt32();

        for (var i = 0; i < numplace; ++i)
        {
            var ind = reader.ReadInt32();
            //WriteLine($"Placeable {i} has index {ind} / {objects.Count}");
            var pos   = reader.ReadVector3();
            var rot   = reader.ReadVector3();
            var size  = reader.ReadVector3();
            var quat  = rot.EulerToQuat();
            var trans = new Transform(new Basis(
                                          quat.xform(new Vector3(1, 0, 0)) * size.x,
                                          quat.xform(new Vector3(0, 1, 0)) * size.y,
                                          quat.xform(new Vector3(0, 0, 1)) * size.z
                                          ), pos);
            oset[ind - 1].Add(trans);
        }
        WriteLine("Parsed ...");
        for (var i = 1; i < numobjs; ++i)
        {
            WriteLine($"Handling placeable {i}/{numobjs}");
            var set = oset[i - 1];
            if (set.Count < 100)              // XXX: Add collision support for multimeshes
            {
                foreach (var trans in set)
                {
                    mi = new MeshInstance()
                    {
                        Mesh = objects[i], Transform = trans
                    };
                    node.AddChild(mi);

                    if (colobjs[i] != null)
                    {
                        var cmi = new MeshInstance()
                        {
                            Mesh = colobjs[i]
                        };
                        cmi.CreateTrimeshCollision();
                        var body = (Spatial)cmi.GetChild(0);
                        cmi.RemoveChild(body);
                        body.Transform = trans;
                        node.AddChild(body);
                    }
                }
            }
            else
            {
                var mmesh = new MultiMesh {
                    TransformFormat = MultiMesh.TRANSFORM_3D,
                    Mesh            = objects[i],
                    InstanceCount   = set.Count
                };
                node.AddChild(new MultiMeshInstance()
                {
                    Multimesh = mmesh
                });

                if (colobjs[i] != null)
                {
                    var cmi = new MeshInstance()
                    {
                        Mesh = colobjs[i]
                    };
                    cmi.CreateTrimeshCollision();
                    var body = (StaticBody)cmi.GetChild(0);
                    cmi.RemoveChild(body);
                    foreach (var trans in set)
                    {
                        var cloned = (StaticBody)body.Duplicate(flags: 0);
                        cloned.Transform = trans;
                        node.AddChild(cloned);
                    }
                }

                for (var j = 0; j < set.Count; ++j)
                {
                    mmesh.SetInstanceTransform(j, set[j]);
                }
            }
        }

        WriteLine("Done loading ... ?");
    }