private void CreateMappingInfo()
        {
            if (column != null)
            {
                if (reflectedType.IsStructure)
                {
                    MappingInfo = new Segment <int>(reflectedType.Columns.IndexOf(column), 1);
                }
                else
                {
                    var primaryIndex = reflectedType.Indexes.PrimaryIndex;
                    var indexColumn  = primaryIndex.Columns.Where(c => c.Name == column.Name).FirstOrDefault();
                    if (indexColumn == null)
                    {
                        throw new InvalidOperationException();
                    }
                    MappingInfo = new Segment <int>(primaryIndex.Columns.IndexOf(indexColumn), 1);
                }
            }
            else
            if (Fields.Count > 0)
            {
                MappingInfo = new Segment <int>(
                    Fields.First().MappingInfo.Offset, Fields.Sum(f => f.IsPrimitive ? f.MappingInfo.Length : 0));
            }

            if (IsEntity || IsStructure)
            {
                valueExtractor = new SegmentTransform(
                    false, reflectedType.TupleDescriptor, new Segment <int>(MappingInfo.Offset, MappingInfo.Length));
            }
        }
        /// <inheritdoc/>
        public override void UpdateState()
        {
            base.UpdateState();

            switch (Multiplicity)
            {
            case Multiplicity.ZeroToOne:
            case Multiplicity.OneToOne:
            case Multiplicity.ManyToOne:
                UnderlyingIndex = OwnerType.Indexes.PrimaryIndex;
                if (!OwnerType.IsInterface)
                {
                    foreignKeyExtractor = OwnerField.valueExtractor;
                }
                break;

            case Multiplicity.OneToMany:
                UnderlyingIndex = Reversed.OwnerField.DeclaringType.Indexes.GetIndex(Reversed.OwnerField.Name);
                break;

            case Multiplicity.ZeroToMany:
            case Multiplicity.ManyToMany:
                if (IsMaster)
                {
                    UnderlyingIndex = auxiliaryType.Indexes.Where(indexInfo => indexInfo.IsSecondary).First();
                }
                else
                {
                    UnderlyingIndex = Reversed.AuxiliaryType.Indexes.Where(indexInfo => indexInfo.IsSecondary).Skip(1).First();
                }

                if (!OwnerType.IsInterface)
                {
                    var foreignKeySegment = new Segment <int>(OwnerType.Columns.Count(c => c.IsPrimaryKey), TargetType.Columns.Count(c => c.IsPrimaryKey));
                    foreignKeyExtractor = new SegmentTransform(true, UnderlyingIndex.TupleDescriptor, foreignKeySegment);
                }
                break;
            }
        }
        public void PerformanceTest2()
        {
            AdvancedComparerStruct <Xtensive.Tuples.Tuple> comparer = AdvancedComparerStruct <Xtensive.Tuples.Tuple> .Default;

            Xtensive.Tuples.Tuple t  = Xtensive.Tuples.Tuple.Create(1);
            CombineTransform      mt = new CombineTransform(false, t.Descriptor, t.Descriptor, t.Descriptor, t.Descriptor);
            SegmentTransform      st = new SegmentTransform(false, mt.Descriptor, new Segment <int>(1, 2));

            Xtensive.Tuples.Tuple wt1 = st.Apply(TupleTransformType.TransformedTuple, mt.Apply(TupleTransformType.TransformedTuple, t, t, t, t));
            Xtensive.Tuples.Tuple wt2 = st.Apply(TupleTransformType.TransformedTuple, mt.Apply(TupleTransformType.TransformedTuple, t, t, t, t));
            Xtensive.Tuples.Tuple ct1 = st.Apply(TupleTransformType.Tuple, mt.Apply(TupleTransformType.Tuple, t, t, t, t));
            Xtensive.Tuples.Tuple ct2 = st.Apply(TupleTransformType.Tuple, mt.Apply(TupleTransformType.Tuple, t, t, t, t));
            int count = IterationCount;

            comparer.Equals(ct1, ct2);
            comparer.Equals(ct1, wt1);
            comparer.Equals(wt1, wt2);

            TestHelper.CollectGarbage();
            using (new Measurement("O&O", MeasurementOptions.Log, count))
                for (int i = 0; i < count; i++)
                {
                    comparer.Equals(ct1, ct2);
                }

            TestHelper.CollectGarbage();
            using (new Measurement("O&W", MeasurementOptions.Log, count))
                for (int i = 0; i < count; i++)
                {
                    comparer.Equals(ct1, wt1);
                }

            TestHelper.CollectGarbage();
            using (new Measurement("W&W", MeasurementOptions.Log, count))
                for (int i = 0; i < count; i++)
                {
                    comparer.Equals(wt1, wt2);
                }
        }
        public void BaseTest()
        {
            Xtensive.Tuples.Tuple t = Xtensive.Tuples.Tuple.Create(1, "2", 3, 4.0);
            TestLog.Info("Original: {0}", t);

            SegmentTransform st   = new SegmentTransform(false, t.Descriptor, new Segment <int>(1, 2));
            SegmentTransform stro = new SegmentTransform(true, t.Descriptor, new Segment <int>(1, 2));

            Xtensive.Tuples.Tuple wt1 = st.Apply(TupleTransformType.TransformedTuple, t);
            TestLog.Info("Wrapper:  {0}", wt1);
            Xtensive.Tuples.Tuple ct1 = st.Apply(TupleTransformType.Tuple, t);
            TestLog.Info("Copy:     {0}", ct1);
            Xtensive.Tuples.Tuple wt2 = st.Apply(TupleTransformType.TransformedTuple, t);
            Xtensive.Tuples.Tuple ct2 = st.Apply(TupleTransformType.Tuple, t);

            Assert.AreEqual(wt1, wt2);
            Assert.AreEqual(wt2, ct1);
            Assert.AreEqual(ct1, ct2);

            wt1.SetValue(1, 1);
            Assert.AreEqual(t.GetValue(2), wt1.GetValue(1));
            Assert.AreEqual(wt1, wt2);
            Assert.AreNotEqual(wt2, ct1);
            Assert.AreEqual(ct1, ct2);

            ct1.SetValue(1, 1);
            Assert.AreEqual(t.GetValue(2), ct1.GetValue(1));
            Assert.AreEqual(wt1, wt2);
            Assert.AreEqual(wt2, ct1);
            Assert.AreNotEqual(ct1, ct2);

            Xtensive.Tuples.Tuple wtro = stro.Apply(TupleTransformType.TransformedTuple, t);
            AssertEx.Throws <NotSupportedException>(delegate {
                wtro.SetValue(1, 1);
            });
        }
    public void BuildMesh() {
        float startTime = Time.realtimeSinceStartup;

        // CritterSegmentTransforms!!
        SegmentTransform[] critterSegmentTransforms = new SegmentTransform[2];
        Quaternion rot = Quaternion.Euler(55f, 12f, -230f);
        Quaternion rot2 = Quaternion.Euler(-35f, 112f, -67f);
        SegmentTransform segmentTransform;
        segmentTransform.PX = 10f;
        segmentTransform.PY = 8f;
        segmentTransform.PZ = 13f;
        segmentTransform.RX = rot.x;
        segmentTransform.RY = rot.y;
        segmentTransform.RZ = rot.z;
        segmentTransform.RW = rot.w;
        segmentTransform.SX = 6f;
        segmentTransform.SY = 7f;
        segmentTransform.SZ = 2.5f;
        SegmentTransform segmentTransform2;
        segmentTransform2.PX = 22f;
        segmentTransform2.PY = 11f;
        segmentTransform2.PZ = 15f;
        segmentTransform2.RX = rot2.x;
        segmentTransform2.RY = rot2.y;
        segmentTransform2.RZ = rot2.z;
        segmentTransform2.RW = rot2.w;
        segmentTransform2.SX = 9f;
        segmentTransform2.SY = 3f;
        segmentTransform2.SZ = 7f;
        critterSegmentTransforms[0] = segmentTransform;
        critterSegmentTransforms[1] = segmentTransform2;

        ComputeBuffer cBufferSegmentTransform = new ComputeBuffer(critterSegmentTransforms.Length, sizeof(float) * (3 + 3 + 4));
        cBufferSegmentTransform.SetData(critterSegmentTransforms);
        int kernelID = CShaderBuildMC.FindKernel("CSMain");
        CShaderBuildMC.SetBuffer(kernelID, "segmentTransformBuffer", cBufferSegmentTransform);

        // Figure out how many chunks are needed:
        int numChunksX = Mathf.CeilToInt(GlobalBoundingBoxDimensions.x * cellResolution / 8f);
        int numChunksY = Mathf.CeilToInt(GlobalBoundingBoxDimensions.y * cellResolution / 8f);
        int numChunksZ = Mathf.CeilToInt(GlobalBoundingBoxDimensions.z * cellResolution / 8f);
        Debug.Log("numChunks: (" + numChunksX.ToString() + ", " + numChunksY.ToString() + ", " + numChunksZ.ToString() + ")");

        int totalNumChunks = numChunksX * numChunksY * numChunksZ;
        Poly[][] PolyArrayArray = new Poly[totalNumChunks][];  // This will hold the mesh data from the chunks calculated on the GPU
        int[] numPolysArray = new int[totalNumChunks];
        int totalNumPolys = 0;

        // Get each chunk!
        int chunkIndex = 0;
        for(int x = 0; x < numChunksX; x++) {
            for(int y = 0; y < numChunksY; y++) {
                for(int z = 0; z < numChunksZ; z++) {
                    // Figure out chunk offset amount:
                    Vector3 chunkOffset = new Vector3(cellResolution * 8f * x, cellResolution * 8f * y, cellResolution * 8f * z);

                    int[] numPolys = new int[1];
                    ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int));
                    cBufferNumPoly.SetData(numPolys);

                    int id = CShaderBuildMC.FindKernel("CSMain");
                    CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer
                    CShaderBuildMC.SetFloat("_GlobalOffsetX", chunkOffset.x);
                    CShaderBuildMC.SetFloat("_GlobalOffsetY", chunkOffset.y);
                    CShaderBuildMC.SetFloat("_GlobalOffsetZ", chunkOffset.z);
                    CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly);
                    CShaderBuildMC.Dispatch(id, 1, 1, 1);  // calc num polys      
                    cBufferNumPoly.GetData(numPolys);  // get numPolys
                    Debug.Log("Chunk: " + (z + (numChunksZ * y) + (numChunksZ * numChunksY * x)).ToString() + ", cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString() + ", chunkIndex: " + chunkIndex.ToString());
                    totalNumPolys += numPolys[0];
                    numPolysArray[chunkIndex] = numPolys[0];

                    //_MaxBufferSize = numPolys[0];
                    if(numPolys[0] > 0) {   // only do this if there was at least 1 triangle in the test pass
                        Poly[] polyArray = new Poly[numPolys[0]];
                        ComputeBuffer cBuffer = new ComputeBuffer(numPolys[0], 72);  // 18 floats x 4 bytes/float = 72
                        cBuffer.SetData(polyArray);

                        CShaderBuildMC.SetBuffer(id, "buffer", cBuffer);
                        CShaderBuildMC.SetInt("_CalcNumPolys", 0);  // Actually calc tris        
                        CShaderBuildMC.Dispatch(id, 1, 1, 1);
                        cBuffer.GetData(polyArray);  // return data from GPU

                        PolyArrayArray[chunkIndex] = polyArray;
                        cBuffer.Dispose();
                    }

                    cBufferNumPoly.Dispose();

                    chunkIndex++;
                }
            }
        }

        //Construct mesh using received data        
        Mesh newMesh = new Mesh();

        int vindex = 0;
                
        // Why same number of tris as vertices?  == // because all triangles have duplicate verts - no shared vertices?
        Vector3[] vertices = new Vector3[totalNumPolys * 3];
        int[] tris = new int[totalNumPolys * 3];
        Vector2[] uvs = new Vector2[totalNumPolys * 3];
        Vector3[] normals = new Vector3[totalNumPolys * 3];

        //Parse triangles
        for(int i = 0; i < PolyArrayArray.Length; i++) {
            if(numPolysArray[i] > 0) {  // only do this if there was at least 1 triangle in the test pass
                for (int ix = 0; ix < numPolysArray[i]; ix++) {

                    Vector3 vPos;
                    Vector3 vOffset = new Vector3(0, 0, 0);   //???  offsets all vertices by this amount, but why 30?? 
                                                              //A1,A2,A3
                    vPos = new Vector3(PolyArrayArray[i][ix].A1, PolyArrayArray[i][ix].A2, PolyArrayArray[i][ix].A3) + vOffset;
                    vertices[vindex] = vPos * _Scale;
                    normals[vindex] = new Vector3(PolyArrayArray[i][ix].NA1, PolyArrayArray[i][ix].NA2, PolyArrayArray[i][ix].NA3);
                    tris[vindex] = vindex;
                    uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x);

                    vindex++;

                    //B1,B2,B3
                    vPos = new Vector3(PolyArrayArray[i][ix].B1, PolyArrayArray[i][ix].B2, PolyArrayArray[i][ix].B3) + vOffset;
                    vertices[vindex] = vPos * _Scale;
                    normals[vindex] = new Vector3(PolyArrayArray[i][ix].NB1, PolyArrayArray[i][ix].NB2, PolyArrayArray[i][ix].NB3);
                    tris[vindex] = vindex;
                    uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x);

                    vindex++;

                    //C1,C2,C3
                    vPos = new Vector3(PolyArrayArray[i][ix].C1, PolyArrayArray[i][ix].C2, PolyArrayArray[i][ix].C3) + vOffset;
                    vertices[vindex] = vPos * _Scale;
                    normals[vindex] = new Vector3(PolyArrayArray[i][ix].NC1, PolyArrayArray[i][ix].NC2, PolyArrayArray[i][ix].NC3);
                    tris[vindex] = vindex;
                    uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x);

                    vindex++;
                }
            }            
        }
        
        //We have got all data and are ready to setup a new mesh!

        //newMesh.Clear();

        newMesh.vertices = vertices;
        newMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh);
        newMesh.triangles = tris;
        newMesh.normals = normals; //NewMesh.RecalculateNormals();
        newMesh.RecalculateNormals();
        newMesh.Optimize();

        //cBuffer.Dispose();
        //cBufferNumPoly.Dispose();
        //cBuffer.Release();
        cBufferSegmentTransform.Release();

        this.GetComponent<MeshFilter>().sharedMesh = newMesh;
        float calcTime = Time.realtimeSinceStartup - startTime;
        Debug.Log("MeshCreated! " + calcTime.ToString());
    }
Example #6
0
    public void BuildMesh()
    {
        float startTime = Time.realtimeSinceStartup;

        // CritterSegmentTransforms!!
        SegmentTransform[] critterSegmentTransforms = new SegmentTransform[2];
        Quaternion         rot  = Quaternion.Euler(55f, 12f, -230f);
        Quaternion         rot2 = Quaternion.Euler(-35f, 112f, -67f);
        SegmentTransform   segmentTransform;

        segmentTransform.PX = 10f;
        segmentTransform.PY = 8f;
        segmentTransform.PZ = 13f;
        segmentTransform.RX = rot.x;
        segmentTransform.RY = rot.y;
        segmentTransform.RZ = rot.z;
        segmentTransform.RW = rot.w;
        segmentTransform.SX = 6f;
        segmentTransform.SY = 7f;
        segmentTransform.SZ = 2.5f;
        SegmentTransform segmentTransform2;

        segmentTransform2.PX        = 22f;
        segmentTransform2.PY        = 11f;
        segmentTransform2.PZ        = 15f;
        segmentTransform2.RX        = rot2.x;
        segmentTransform2.RY        = rot2.y;
        segmentTransform2.RZ        = rot2.z;
        segmentTransform2.RW        = rot2.w;
        segmentTransform2.SX        = 9f;
        segmentTransform2.SY        = 3f;
        segmentTransform2.SZ        = 7f;
        critterSegmentTransforms[0] = segmentTransform;
        critterSegmentTransforms[1] = segmentTransform2;

        ComputeBuffer cBufferSegmentTransform = new ComputeBuffer(critterSegmentTransforms.Length, sizeof(float) * (3 + 3 + 4));

        cBufferSegmentTransform.SetData(critterSegmentTransforms);
        int kernelID = CShaderBuildMC.FindKernel("CSMain");

        CShaderBuildMC.SetBuffer(kernelID, "segmentTransformBuffer", cBufferSegmentTransform);

        // Figure out how many chunks are needed:
        int numChunksX = Mathf.CeilToInt(GlobalBoundingBoxDimensions.x * cellResolution / 8f);
        int numChunksY = Mathf.CeilToInt(GlobalBoundingBoxDimensions.y * cellResolution / 8f);
        int numChunksZ = Mathf.CeilToInt(GlobalBoundingBoxDimensions.z * cellResolution / 8f);

        Debug.Log("numChunks: (" + numChunksX.ToString() + ", " + numChunksY.ToString() + ", " + numChunksZ.ToString() + ")");

        int totalNumChunks = numChunksX * numChunksY * numChunksZ;

        Poly[][] PolyArrayArray = new Poly[totalNumChunks][];  // This will hold the mesh data from the chunks calculated on the GPU
        int[]    numPolysArray  = new int[totalNumChunks];
        int      totalNumPolys  = 0;

        // Get each chunk!
        int chunkIndex = 0;

        for (int x = 0; x < numChunksX; x++)
        {
            for (int y = 0; y < numChunksY; y++)
            {
                for (int z = 0; z < numChunksZ; z++)
                {
                    // Figure out chunk offset amount:
                    Vector3 chunkOffset = new Vector3(cellResolution * 8f * x, cellResolution * 8f * y, cellResolution * 8f * z);

                    int[]         numPolys       = new int[1];
                    ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int));
                    cBufferNumPoly.SetData(numPolys);

                    int id = CShaderBuildMC.FindKernel("CSMain");
                    CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer
                    CShaderBuildMC.SetFloat("_GlobalOffsetX", chunkOffset.x);
                    CShaderBuildMC.SetFloat("_GlobalOffsetY", chunkOffset.y);
                    CShaderBuildMC.SetFloat("_GlobalOffsetZ", chunkOffset.z);
                    CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly);
                    CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys
                    cBufferNumPoly.GetData(numPolys);     // get numPolys
                    Debug.Log("Chunk: " + (z + (numChunksZ * y) + (numChunksZ * numChunksY * x)).ToString() + ", cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString() + ", chunkIndex: " + chunkIndex.ToString());
                    totalNumPolys            += numPolys[0];
                    numPolysArray[chunkIndex] = numPolys[0];

                    //_MaxBufferSize = numPolys[0];
                    if (numPolys[0] > 0)     // only do this if there was at least 1 triangle in the test pass
                    {
                        Poly[]        polyArray = new Poly[numPolys[0]];
                        ComputeBuffer cBuffer   = new ComputeBuffer(numPolys[0], 72); // 18 floats x 4 bytes/float = 72
                        cBuffer.SetData(polyArray);

                        CShaderBuildMC.SetBuffer(id, "buffer", cBuffer);
                        CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris
                        CShaderBuildMC.Dispatch(id, 1, 1, 1);
                        cBuffer.GetData(polyArray);                // return data from GPU

                        PolyArrayArray[chunkIndex] = polyArray;
                        cBuffer.Dispose();
                    }

                    cBufferNumPoly.Dispose();

                    chunkIndex++;
                }
            }
        }

        //Construct mesh using received data
        Mesh newMesh = new Mesh();

        int vindex = 0;

        // Why same number of tris as vertices?  == // because all triangles have duplicate verts - no shared vertices?
        Vector3[] vertices = new Vector3[totalNumPolys * 3];
        int[]     tris     = new int[totalNumPolys * 3];
        Vector2[] uvs      = new Vector2[totalNumPolys * 3];
        Vector3[] normals  = new Vector3[totalNumPolys * 3];

        //Parse triangles
        for (int i = 0; i < PolyArrayArray.Length; i++)
        {
            if (numPolysArray[i] > 0)    // only do this if there was at least 1 triangle in the test pass
            {
                for (int ix = 0; ix < numPolysArray[i]; ix++)
                {
                    Vector3 vPos;
                    Vector3 vOffset = new Vector3(0, 0, 0);   //???  offsets all vertices by this amount, but why 30??
                                                              //A1,A2,A3
                    vPos             = new Vector3(PolyArrayArray[i][ix].A1, PolyArrayArray[i][ix].A2, PolyArrayArray[i][ix].A3) + vOffset;
                    vertices[vindex] = vPos * _Scale;
                    normals[vindex]  = new Vector3(PolyArrayArray[i][ix].NA1, PolyArrayArray[i][ix].NA2, PolyArrayArray[i][ix].NA3);
                    tris[vindex]     = vindex;
                    uvs[vindex]      = new Vector2(vertices[vindex].z, vertices[vindex].x);

                    vindex++;

                    //B1,B2,B3
                    vPos             = new Vector3(PolyArrayArray[i][ix].B1, PolyArrayArray[i][ix].B2, PolyArrayArray[i][ix].B3) + vOffset;
                    vertices[vindex] = vPos * _Scale;
                    normals[vindex]  = new Vector3(PolyArrayArray[i][ix].NB1, PolyArrayArray[i][ix].NB2, PolyArrayArray[i][ix].NB3);
                    tris[vindex]     = vindex;
                    uvs[vindex]      = new Vector2(vertices[vindex].z, vertices[vindex].x);

                    vindex++;

                    //C1,C2,C3
                    vPos             = new Vector3(PolyArrayArray[i][ix].C1, PolyArrayArray[i][ix].C2, PolyArrayArray[i][ix].C3) + vOffset;
                    vertices[vindex] = vPos * _Scale;
                    normals[vindex]  = new Vector3(PolyArrayArray[i][ix].NC1, PolyArrayArray[i][ix].NC2, PolyArrayArray[i][ix].NC3);
                    tris[vindex]     = vindex;
                    uvs[vindex]      = new Vector2(vertices[vindex].z, vertices[vindex].x);

                    vindex++;
                }
            }
        }

        //We have got all data and are ready to setup a new mesh!

        //newMesh.Clear();

        newMesh.vertices  = vertices;
        newMesh.uv        = uvs;     //Unwrapping.GeneratePerTriangleUV(NewMesh);
        newMesh.triangles = tris;
        newMesh.normals   = normals; //NewMesh.RecalculateNormals();
        newMesh.RecalculateNormals();
        newMesh.Optimize();

        //cBuffer.Dispose();
        //cBufferNumPoly.Dispose();
        //cBuffer.Release();
        cBufferSegmentTransform.Release();

        this.GetComponent <MeshFilter>().sharedMesh = newMesh;
        float calcTime = Time.realtimeSinceStartup - startTime;

        Debug.Log("MeshCreated! " + calcTime.ToString());
    }