예제 #1
0
        /// <summary>
        /// Loads index data from a mesh
        /// </summary>
        protected bool LoadIndexData(Mesh mesh, int partitionIndex)
        {
            MeshPart part = mesh.GetPartition(partitionIndex);

            TriangleCount = (uint)part.TriangleCount;
            var indexList = new List <ushort> ();

            for (int fi = part.StartFaceIndex; fi < part.EndFaceIndex; fi++)
            {
                var f = mesh.Faces [fi];

                int i0 = f.A; int i1 = f.B; int i2 = f.C; int i3 = f.D;

                indexList.Add((ushort)(i0 - part.StartVertexIndex));
                indexList.Add((ushort)(i1 - part.StartVertexIndex));
                indexList.Add((ushort)(i2 - part.StartVertexIndex));
                if (i2 != i3)
                {
                    indexList.Add((ushort)(i2 - part.StartVertexIndex));
                    indexList.Add((ushort)(i3 - part.StartVertexIndex));
                    indexList.Add((ushort)(i0 - part.StartVertexIndex));
                }
            }

            ushort[] indices = indexList.ToArray();
            IndexBufferLength = indices.Length;
            indexList.Clear();

            GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)(indices.Length * sizeof(ushort)), indices, BufferUsage.StaticDraw);

            return(indices.Length > 0);
        }
예제 #2
0
        /// <summary>
        /// Loads vertex, normal, and color data from a mesh, given a partition index
        /// </summary>
        protected bool LoadVertexNormalColorData(Mesh mesh, int partitionIndex)
        {
            Stride = (Marshal.SizeOf(typeof(VNCData)));              // This should be 40 bytes

            MeshPart meshPartition = mesh.GetPartition(partitionIndex);
            int      vertexCount   = meshPartition.VertexCount;
            int      startIndex    = meshPartition.StartVertexIndex;
            int      endIndex      = meshPartition.EndVertexIndex;

            int count = (endIndex - startIndex) * 3;

            VNCData[] verticesNormalsColors = new VNCData[count];

            for (int i = startIndex; i < endIndex; i++)
            {
                verticesNormalsColors [i - startIndex].Vertex = mesh.Vertices [i];
                verticesNormalsColors [i - startIndex].Normal = mesh.Normals [i];
                verticesNormalsColors [i - startIndex].Color  = new Color4f(mesh.VertexColors [i]);
            }

            TriangleCount += (uint)mesh.Faces.Count;

            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(verticesNormalsColors.Length * Stride), verticesNormalsColors, BufferUsage.StaticDraw);

            return(verticesNormalsColors.Length > 0);
        }
예제 #3
0
        private void HeadMesh_OnBeforePartDraw(MeshPart part)
        {
            var transparent = UseTexture ? part.TransparentTexture : 0.0f;

            if (transparent > 0.0f)
            {
                EnableTransparent();
            }
            else
            {
                DisableTransparent();
            }

            var shader      = idleShader;
            var useTextures = Vector3.Zero;

            GL.ActiveTexture(TextureUnit.Texture1);
            GL.BindTexture(TextureTarget.Texture2D, part.TransparentTexture);
            shader.UpdateUniform("u_TransparentMap", 1);
            //shader.UpdateUniform("u_UseTransparent", transparent);
            useTextures.Y = transparent;

            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, part.Texture);
            shader.UpdateUniform("u_Texture", 0);
            useTextures.X = UseTexture ? part.Texture : 0.0f;
            //shader.UpdateUniform("u_UseTexture", UseTexture ? part.Texture : 0.0f);
            shader.UpdateUniform("u_Color", part.Color);

            shader.UpdateUniform("u_UseTexture", useTextures);
        }
예제 #4
0
        private void MeshAddPartButton_Click(object sender, RoutedEventArgs e)
        {
            var meshString = MeshComboBox.SelectedItem.ToString();
            var meshNum    = int.Parse(meshString);

            MeshPart newPart = new MeshPart();

            modelData.LoD[0].MeshList[meshNum].MeshPartList.Add(newPart);

            newPart = new MeshPart();
            modelData.LoD[1].MeshList[meshNum].MeshPartList.Add(newPart);

            newPart = new MeshPart();
            modelData.LoD[2].MeshList[meshNum].MeshPartList.Add(newPart);

            MeshPartCount.Content = modelData.LoD[0].MeshList[meshNum].MeshPartList.Count;
            MeshPartCount.Content = modelData.LoD[1].MeshList[meshNum].MeshPartList.Count;
            MeshPartCount.Content = modelData.LoD[2].MeshList[meshNum].MeshPartList.Count;

            List <int> parts = (List <int>)PartComboBox.ItemsSource;

            parts.Add(modelData.LoD[0].MeshList[meshNum].MeshPartList.Count - 1);
            PartComboBox.ItemsSource   = null;
            PartComboBox.ItemsSource   = parts;
            PartComboBox.SelectedIndex = 0;
        }
예제 #5
0
        public void Draw(CommandList cmdList, Camera cam)
        {
            cmdList.SetVertexBuffer(0, m_vertexBuffer);
            cmdList.SetIndexBuffer(m_indexBuffer, IndexFormat.UInt32);
            cmdList.SetPipeline(m_pipelineState);

            SN.Matrix4x4 transform = WorldMatrix;

            for (int i = 0; i < m_meshesToDraw.Count; i++)
            {
                MeshDrawCall   drawParams = m_meshesToDraw[i];
                MeshPart       partData   = m_meshesData[drawParams.MeshPartIndex];
                SimpleMaterial material   = m_materials[partData.MaterialIndex];

                SN.Matrix4x4 w   = drawParams.World * transform;
                SN.Matrix4x4 wvp = w * cam.ViewProjection;

                cmdList.UpdateBuffer(m_wvpParam, 0, ref wvp);
                cmdList.UpdateBuffer(m_worldParam, 0, ref w);
                cmdList.UpdateBuffer(m_lightPosParam, 0, LightPosition);
                cmdList.UpdateBuffer(m_camPosParam, 0, cam.Position);

                cmdList.SetGraphicsResourceSet(0, m_worldLightCBSet);
                cmdList.SetGraphicsResourceSet(1, material.ColorAndTexture);

                cmdList.DrawIndexed((uint)partData.IndexCount, 1, (uint)partData.IndexOffset, 0, 0);
            }
        }
예제 #6
0
        public void Bind(MeshPart value)
        {
            _lastmeshPart = value;
            #region Compute Bone Matrices

            var bonesIDs = _skin.GetBones(value);
            if (bonesIDs != null)
            {
                int paletteEntry = 0;
                for (paletteEntry = 0; paletteEntry < bonesIDs.Length; paletteEntry++)
                {
                    int boneIndex = bonesIDs[paletteEntry];

                    Matrix globalPose = _bones[boneIndex].GlobalPose;

                    Matrix.Multiply(ref _bindShapePose, ref _boneOffsetMatrices[boneIndex], out _boneMatrices[paletteEntry]);
                    Matrix.Multiply(ref _boneMatrices[paletteEntry], ref globalPose, out _boneMatrices[paletteEntry]);
                    //boneMatrices[paletteEntry] = skin.BindShapePose * boneOffsetMatrices[boneIndex] * bones[boneIndex].GlobalPose;
                }

                if (Mapping != null)
                {
                    Mapping.WorldArray = new SArray <Matrix>(_boneMatrices, paletteEntry);
                    //mapping.WorldArray = boneMatrices;
                }
            }
            #endregion
        }
예제 #7
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh mesh        = null;
            int  maxVertices = 0;

            if (!DA.GetData(0, ref mesh))
            {
                return;
            }
            if (!DA.GetData(1, ref maxVertices))
            {
                return;
            }

            mesh.CreatePartitions(maxVertices, maxVertices * 2);
            List <GH_Mesh> newMeshes = new List <GH_Mesh>();

            for (int i = 0; i < mesh.PartitionCount; i++)
            {
                MeshPart meshPart = mesh.GetPartition(i);
                IEnumerable <MeshFace> meshFaces = mesh.Faces.Skip(meshPart.StartFaceIndex).Take(meshPart.EndFaceIndex - meshPart.StartFaceIndex);

                Mesh partMesh = new Mesh();
                partMesh.Vertices.AddVertices(mesh.Vertices);
                partMesh.Faces.AddFaces(meshFaces);
                partMesh.Normals.ComputeNormals();
                partMesh.Compact();

                GH_Mesh ghmesh = new GH_Mesh(partMesh);

                newMeshes.Add(ghmesh);
            }

            DA.SetDataList(0, newMeshes);
        }
예제 #8
0
    void LeftClick()
    {
        Collider[] cols = Physics.OverlapSphere(transform.position, 1.5f);
        float      min  = 1000f;

        Vector3 closestPoint = Vector3.zero;

        GameObject o = null;

        foreach (Collider col in cols)
        {
            if (col.gameObject.name != "Trigger" && col.gameObject.tag != "Player")
            {
                Vector3 p = col.bounds.ClosestPoint(transform.position);
                float   d = (p - transform.position).sqrMagnitude;

                if (d < min)
                {
                    min          = d;
                    closestPoint = p;
                    o            = col.gameObject;
                }
            }
        }


        if (closestPoint == Vector3.zero)
        {
            return;
        }

        Vector3 dir = fwd.position - cam.position;

        GameObject obj = Instantiate(basicTentacle, Vector3.zero, Quaternion.identity) as GameObject;

        Tentacle t = obj.GetComponent <Tentacle> ();

        if (o.GetComponent <MeshPart> ())
        {
            MeshPart omp = o.GetComponent <MeshPart> ();

            t.origin       = omp.startPosition;
            t.customOrigin = true;
            t.startRadius  = omp.startRadius * 1.3f;
            t.direction    = dir.normalized;
        }
        else
        {
            t.origin    = transform.position;
            t.direction = dir.normalized;

            t.origin = closestPoint;
        }
        t.Go();
    }
예제 #9
0
 public override void DrawSubObjekt(RenderInformation RI, MeshPart M, GraphicNode GN)
 {
     Device.Context.VertexShader.SetConstantBuffer(cBuf, 0);
     Device.Context.PixelShader.SetConstantBuffer(cBuf2, 1);
     if (M == null || M.Buffer == null || M.Buffer.VertexCount == 0) return;
     Device.InputAssembler.SetVertexBuffer(0, M.Buffer.Bindings[0]);
     if(M.Material.DiffuseTexture != null)
         Device.Context.PixelShader.SetShaderResource(M.Material.DiffuseTexture.ShaderResourceView, 0);
     else Device.Context.PixelShader.SetShaderResource(ShaderResourceTexture.WhiteTexture.ShaderResourceView, 0);
     Device.Context.Draw(M.Buffer.VertexCount, 0);
 }
예제 #10
0
        private void DrawMeshPart(Mesh mesh, MeshPart part, GraphicDevice device)
        {
            device.SetVertexBuffer(0, mesh.VertexBuffer, 0);
            device.SetIndexBuffer(mesh.IndexBuffer);
            var effect = Effect;

            foreach (var pass in effect.Passes())
            {
                effect.Apply(pass);
                device.DrawIndexed(part.IndexCount, part.StartIndex, 0);
            }
        }
예제 #11
0
        protected void convertMesh(ModelMesh modelMesh)
        {
            var numIndices = 0;

            foreach (var part in modelMesh.parts)
            {
                numIndices += part.indices.Length;
            }

            var attributes  = new VertexAttributes(modelMesh.attributes);
            var numVertices = modelMesh.vertices.Length / (attributes.vertexSize / 4);

            numVertices = modelMesh.vertices.Length;
            var mesh = new Mesh(true, numVertices, numIndices, attributes);

            meshes.Add(mesh);
            disposables.Add(mesh);

            // src, dst, num, offset
            //mesh.setVertices(new float[modelMesh.vertices.Length]);
            //Array.Copy(modelMesh.vertices, mesh.getVerticesBuffer(), modelMesh.vertices.Length);
            mesh.setVertices(modelMesh.vertices);

            var list   = new List <uint>();
            var offset = 0;

            foreach (var part in modelMesh.parts)
            {
                var meshPart = new MeshPart();
                meshPart.id            = part.id;
                meshPart.primitiveType = part.primitiveType;
                meshPart.offset        = offset;
                meshPart.size          = part.indices.Length;
                meshPart.mesh          = mesh;
                //mesh.getIndicesBuffer().put(part.indices);

                // todo: optimize
                list.AddRange(part.indices.ToList());

                offset += meshPart.size;


                meshParts.Add(meshPart);
            }

            mesh.setIndices(list.ToArray());

            foreach (var part in meshParts)
            {
                part.update();
            }
        }
예제 #12
0
        MeshPartDefinition ToMeshPartDefinition(MeshPart meshPart)
        {
            if (meshPart == null)
            {
                return(new MeshPartDefinition());
            }

            return(new MeshPartDefinition
            {
                Vertices = meshPart.Vertices,
                Indices = meshPart.Indices
            });
        }
예제 #13
0
            public void Initialize(CollisionFunctor cf, PolyhedronPart a, MeshPart b, Vector3 delta)
            {
                _cf           = cf;
                _a            = a;
                _b            = b;
                _delta        = delta;
                _useSweptTest = _delta != Vector3.Zero;
                Depth         = float.MaxValue;
                a.Center(out _center);

                // transform bounding box to body space
                b.BoundingBox(out BoundingBox);
                AlignedBox.Transform(ref BoundingBox, ref b.TransformInverse, out BoundingBox);
            }
예제 #14
0
    void BuildMeshes()
    {
        for (int i = 0; i < partNumber; i++)
        {
            GameObject m = new GameObject();

            m.AddComponent <MeshFilter> ();
            m.AddComponent <MeshRenderer> ();

            MeshCollider mC   = m.AddComponent <MeshCollider> ();
            MeshPart     mesh = m.AddComponent <MeshPart> ();

            m.GetComponent <MeshRenderer> ().material = sectionMat;

            mesh.numberOfSides = numberOfSides;
            mesh.noise         = sectionNoise;

            mesh.startRadius    = 0.01f;
            mesh.startPosition  = points [i];
            mesh.startDirection = directions [i];

            mesh.endRadius    = 0.01f;
            mesh.endPosition  = points [i + 1];
            mesh.endDirection = directions [i + 1];

            mesh.tentacle = this;

            mesh.resistance = (3.14f * endRadiuses [i] * mesh.length * volumicResistance) / (gravityFragility);

            mesh.Init();

            mC.sharedMesh = mesh.GetComponent <MeshFilter> ().mesh;
            mC.convex     = true;

            sections [i] = mesh;

            if (i == 0)
            {
                mesh.transform.SetParent(transform);
            }
            else
            {
                mesh.transform.SetParent(sections [i - 1].transform);
            }


            sections [i].gameObject.SetActive(false);
        }
    }
예제 #15
0
			public void Initialize(CollisionFunctor cf, SpherePart a, MeshPart b)
			{
				_cf = cf;
				_a = a;
				_b = b;
				_radius = a.World.Radius * b.TransformInverse.Scale;
				_radiusSquared = _radius * _radius;
				Depth = float.MaxValue;

				Vector3.Transform(ref a.World.Center, ref b.TransformInverse.Combined, out _center);
				BoundingBox.Minimum = BoundingBox.Maximum = _center;
				var radius = new Vector3(_radius);
				Vector3.Subtract(ref BoundingBox.Minimum, ref radius, out BoundingBox.Minimum);
				Vector3.Add(ref BoundingBox.Maximum, ref radius, out BoundingBox.Maximum);
			}
예제 #16
0
            public void Initialize(CollisionFunctor cf, SpherePart a, MeshPart b)
            {
                _cf            = cf;
                _a             = a;
                _b             = b;
                _radius        = a.World.Radius * b.TransformInverse.Scale;
                _radiusSquared = _radius * _radius;
                Depth          = float.MaxValue;

                Vector3.Transform(ref a.World.Center, ref b.TransformInverse.Combined, out _center);
                BoundingBox.Minimum = BoundingBox.Maximum = _center;
                var radius = new Vector3(_radius);

                Vector3.Subtract(ref BoundingBox.Minimum, ref radius, out BoundingBox.Minimum);
                Vector3.Add(ref BoundingBox.Maximum, ref radius, out BoundingBox.Maximum);
            }
        public StudioMdlWriter AssembleModel(Folder characterAssets, AvatarScale scale, bool collisionModel = false)
        {
            StudioMdlWriter meshBuilder = new StudioMdlWriter();

            // Build Character
            Folder import   = RBXM.LoadFromAsset(R6AssemblyAsset);
            Folder assembly = import.FindFirstChild <Folder>("ASSEMBLY");

            assembly.Parent = characterAssets;

            BasePart head  = assembly.FindFirstChild <BasePart>("Head");
            BasePart torso = assembly.FindFirstChild <BasePart>("Torso");

            torso.CFrame = new CFrame();

            foreach (Instance asset in characterAssets.GetChildren())
            {
                if (asset.IsA("CharacterMesh") && !collisionModel)
                {
                    CharacterMesh characterMesh = (CharacterMesh)asset;
                    string        limbName      = LimbMatcher[characterMesh.BodyPart];

                    MeshPart limb = assembly.FindFirstChild <MeshPart>(limbName);
                    if (limb != null)
                    {
                        limb.MeshId = "rbxassetid://" + characterMesh.MeshId;
                    }
                }
                else if (asset.IsA("Accoutrement") && !collisionModel)
                {
                    PrepareAccessory(asset, assembly);
                }
                else if (asset.IsA("DataModelMesh"))
                {
                    OverwriteHead(asset, head);
                }
            }

            BoneKeyframe keyframe = AssembleBones(meshBuilder, torso);

            foreach (Bone bone in keyframe.Bones)
            {
                BuildAvatarGeometry(meshBuilder, bone);
            }

            return(meshBuilder);
        }
예제 #18
0
        public void InitializeTexCoords(ref Vector2 v1, ref Vector2 v2, ref Vector2 v3,
                                        ref Vector2 vm1, ref Vector2 vm2, ref Vector2 vm3,
                                        MeshPart meshPart)
        {
            foreach (var i in Indices)
            {
                var v = meshPart.Vertices[i];

                v.AutodotsTexCoord.X = FrontTriangle.U * v1.X + FrontTriangle.V * v2.X + FrontTriangle.W * v3.X;
                v.AutodotsTexCoord.Y = FrontTriangle.U * v1.Y + FrontTriangle.V * v2.Y + FrontTriangle.W * v3.Y;

                v.AutodotsTexCoord.Z = FrontTriangle.U * vm1.X + FrontTriangle.V * vm2.X + FrontTriangle.W * vm3.X;
                v.AutodotsTexCoord.W = FrontTriangle.U * vm1.Y + FrontTriangle.V * vm2.Y + FrontTriangle.W * vm3.Y;

                meshPart.Vertices[i] = v;
            }
        }
예제 #19
0
        public static bool ShouldDisplay(this MeshPart part, string[] invisMeshAttrs)
        {
            bool display = true;

            foreach (ModelAttribute attr in part.Attributes)
            {
                foreach (string visible in invisMeshAttrs)
                {
                    if (attr.Name.EndsWith(visible))
                    {
                        display = false;
                    }
                }
            }

            return(display);
        }
예제 #20
0
        /// <summary>
        /// Creates a default material fitting the given model mesh part
        /// </summary>
        /// <param name="meshPart"></param>
        /// <param name="graphicsDevice"></param>
        /// <returns></returns>
        public static EffectMaterial CreateDefaultMaterial(MeshPart meshPart, GraphicsDevice graphicsDevice)
        {
            BasicEffect effect = new BasicEffect(graphicsDevice);
            Dictionary <String, Object> effectParameters = new Dictionary <string, object>();
            Material material = new Material();

            if (meshPart.Vertices.HasElement(VertexElementUsage.Color))
            {
                effect.VertexColorEnabled = true;
            }

            if (meshPart.Vertices.HasElement(VertexElementUsage.Normal))
            {
                effect.EnableDefaultLighting();
            }

            return(new EffectMaterial("Default Material", effect, effectParameters, material));
        }
예제 #21
0
			public void Initialize(CollisionFunctor cf, CapsulePart a, MeshPart b, Vector3 offset)
			{
				_cf = cf;
				_b = b;
				_radius = a.World.Radius * b.TransformInverse.Scale;
				_radiusSquared = _radius * _radius;
				_offset = offset;
				_hasCollision = false;
				Vector3.Add(ref a.World.P1, ref _offset, out _cap.P1);
				Vector3.Add(ref a.World.P2, ref _offset, out _cap.P2);

				// calculate points and bounding box in body space
				var radius = new Vector3(_radius);
				Vector3.Transform(ref _cap.P1, ref b.TransformInverse.Combined, out _cap.P1);
				Vector3.Transform(ref _cap.P2, ref b.TransformInverse.Combined, out _cap.P2);
				AlignedBox.Fit(ref _cap.P1, ref _cap.P2, out BoundingBox);
				Vector3.Subtract(ref BoundingBox.Minimum, ref radius, out BoundingBox.Minimum);
				Vector3.Add(ref BoundingBox.Maximum, ref radius, out BoundingBox.Maximum);
			}
예제 #22
0
            public void Initialize(CollisionFunctor cf, SpherePart a, MeshPart b, Vector3 delta)
            {
                _cf            = cf;
                _a             = a;
                _b             = b;
                _radius        = a.World.Radius * b.TransformInverse.Scale;
                _radiusSquared = _radius * _radius;

                Vector3.Transform(ref a.World.Center, ref b.TransformInverse.Combined, out _path.P1);
                Vector3.Transform(ref delta, ref b.TransformInverse.Orientation, out delta);
                Vector3.Multiply(ref delta, b.TransformInverse.Scale, out delta);
                Vector3.Add(ref _path.P1, ref delta, out _path.P2);

                AlignedBox.Fit(ref _path.P1, ref _path.P2, out BoundingBox);

                var radius = new Vector3(_radius);

                Vector3.Subtract(ref BoundingBox.Minimum, ref radius, out BoundingBox.Minimum);
                Vector3.Add(ref BoundingBox.Maximum, ref radius, out BoundingBox.Maximum);
            }
예제 #23
0
            public void Initialize(CollisionFunctor cf, CapsulePart a, MeshPart b, Vector3 offset)
            {
                _cf            = cf;
                _b             = b;
                _radius        = a.World.Radius * b.TransformInverse.Scale;
                _radiusSquared = _radius * _radius;
                _offset        = offset;
                _hasCollision  = false;
                Vector3.Add(ref a.World.P1, ref _offset, out _cap.P1);
                Vector3.Add(ref a.World.P2, ref _offset, out _cap.P2);

                // calculate points and bounding box in body space
                var radius = new Vector3(_radius);

                Vector3.Transform(ref _cap.P1, ref b.TransformInverse.Combined, out _cap.P1);
                Vector3.Transform(ref _cap.P2, ref b.TransformInverse.Combined, out _cap.P2);
                AlignedBox.Fit(ref _cap.P1, ref _cap.P2, out BoundingBox);
                Vector3.Subtract(ref BoundingBox.Minimum, ref radius, out BoundingBox.Minimum);
                Vector3.Add(ref BoundingBox.Maximum, ref radius, out BoundingBox.Maximum);
            }
예제 #24
0
        static void WriteIndices <T>(StreamWriter writer, MeshPart mp, Func <T, int> formatter, ParsingFlags ps) where T : struct
        {
            IndexBuffer iBuffer = mp.IBuffer;

            T[] data  = new T[mp.NumIndices];
            int iSize = mp.IBuffer.IndexElementSize == IndexElementSize.SixteenBits ? 2 : 4;

            mp.IBuffer.GetData(mp.StartIndex * iSize, data, 0, data.Length);
            int i = 0;

            while (i < data.Length)
            {
                writer.Write("f");
                for (int vi = 0; vi < 3 && i < data.Length; vi++)
                {
                    int vert;
                    if (ps.HasFlag(ParsingFlags.FlipTriangleOrder))
                    {
                        vert = formatter(data[i + (2 - vi)]) + 1;
                    }
                    else
                    {
                        vert = formatter(data[i + vi]) + 1;
                    }

                    writer.Write(" " + vert);
                    writer.Write("/");
                    if (ps.HasFlag(ParsingFlags.WriteUV))
                    {
                        writer.Write(vert);
                    }
                    writer.Write("/");
                    if (ps.HasFlag(ParsingFlags.WriteNorms))
                    {
                        writer.Write(vert);
                    }
                }
                i += 3;
                writer.WriteLine("");
            }
        }
예제 #25
0
        private void AddMeshButton_Click(object sender, RoutedEventArgs e)
        {
            for (int l = 0; l < modelData.LoD.Count; l++)
            {
                var mesh    = new Mesh();
                var newPart = new MeshPart();
                mesh.MeshPartList = new List <MeshPart>();
                mesh.MeshPartList.Add(newPart);
                modelData.LoD[l].MeshList.Add(mesh);
                modelData.LoD[l].MeshCount += 1;
            }

            for (int l = 1; l < modelData.LoD.Count; l++)
            {
                while (modelData.LoD[l].MeshCount < modelData.LoD[0].MeshCount)
                {
                    var mesh    = new Mesh();
                    var newPart = new MeshPart();
                    mesh.MeshPartList = new List <MeshPart>();
                    mesh.MeshPartList.Add(newPart);
                    modelData.LoD[l].MeshList.Add(mesh);
                    modelData.LoD[l].MeshCount += 1;
                }
            }

            importDict.Add((modelData.LoD[0].MeshCount - 1).ToString(), new ImportSettings());


            List <string> meshCounts = new List <string>();

            meshCounts.Add("ALL");
            for (int i = 0; i < modelData.LoD[0].MeshCount; i++)
            {
                meshCounts.Add(i.ToString());
            }
            MeshComboBox.ItemsSource   = meshCounts;
            MeshComboBox.SelectedIndex = 0;

            MeshCountLabel.Content = "Meshes: " + modelData.LoD[0].MeshCount;
        }
예제 #26
0
    void UpdateRadiusesOverTime(float timeFromGrowthStart)
    {
        float T = timeFromGrowthStart / timeToFullyGrow;

        if (T == 1)
        {
            nRadiuses = endRadiuses;
        }
        else
        {
            nRadiuses.Clear();
            for (int i = 0; i < partNumber; i++)
            {
                float pos = (float)i / (float)partNumber;

                float nRadius = endRadiuses[i] * sectionRadiusOverTime.Evaluate(T);

                nRadiuses.Add(nRadius);
            }

            nRadiuses.Add(0.001f);
        }

        for (int i = 0; i < partNumber; i++)
        {
            MeshPart mesh = sections [i];

            mesh.startRadius = nRadiuses [i] + 0.01f;
            mesh.endRadius   = nRadiuses [i + 1] + 0.01f;

            mesh.UpdateMesh();
            UpdateCollider(mesh.gameObject);

            if (mesh.startRadius > 0.1f)
            {
                mesh.gameObject.SetActive(true);
            }
        }
    }
예제 #27
0
        public static void WriteObj(MeshPart mp, StreamWriter writer, ParsingFlags ps = ParsingFlags.WriteAll)
        {
            ParsingFlags capable = ParsingFlags.None;

            // Loop Through All Vertex Elements
            VertexElement[] elements = mp.VBuffer.VertexDeclaration.GetVertexElements();
            foreach (VertexElement ve in elements)
            {
                // Choose Formatting Functions By Type
                switch (ve.VertexElementFormat)
                {
                case VertexElementFormat.Vector2: WriteElement <Vector2>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Vector3: WriteElement <Vector3>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Vector4: WriteElement <Vector4>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Single: WriteElement <float>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Color: WriteElement <Color>(writer, ve, mp, Format, ref capable); break;

                case VertexElementFormat.Byte4: WriteElement <Color>(writer, ve, mp, Format, ref capable); break;

                default:
                    // Those Are The Basic Types
                    break;
                }
            }
            // Only Write What Is Capable
            ps &= capable;

            // Write Indices
            switch (mp.IBuffer.IndexElementSize)
            {
            case IndexElementSize.SixteenBits: WriteIndices <short>(writer, mp, Format, ps); break;

            case IndexElementSize.ThirtyTwoBits: WriteIndices <int>(writer, mp, Format, ps); break;
            }
        }
예제 #28
0
    MeshPart GenerateMesh(MeshPart mesh, Bounds bounds, bool inside)
    {
        MeshPart result = new MeshPart(mesh.sourceTransform);

        // Create new mesh with the triangles that are inside of the bounds.
        for (int i = 0; i < mesh.triangles.Count; i++)
        {
            int[] triangle = mesh.triangles[i].ToArray();

            for (int j = 0; j < triangle.Length; j += 3)
            {
                int amountOfPointsInside = 0;
                if (bounds.Contains(mesh.sourceTransform.TransformPoint(mesh.vertices[triangle[j]])))
                {
                    amountOfPointsInside++;
                }
                if (bounds.Contains(mesh.sourceTransform.TransformPoint(mesh.vertices[triangle[j + 1]])))
                {
                    amountOfPointsInside++;
                }
                if (bounds.Contains(mesh.sourceTransform.TransformPoint(mesh.vertices[triangle[j + 2]])))
                {
                    amountOfPointsInside++;
                }

                // Most of the points are inside of the bounds, keep this triangle.
                if (amountOfPointsInside >= 2 == inside)
                {
                    result.AddTriangle(i,
                                       mesh.vertices[triangle[j]], mesh.vertices[triangle[j + 1]], mesh.vertices[triangle[j + 2]],
                                       mesh.normals[triangle[j]], mesh.normals[triangle[j + 1]], mesh.normals[triangle[j + 2]],
                                       mesh.uVs[triangle[j]], mesh.uVs[triangle[j + 1]], mesh.uVs[triangle[j + 2]]);
                }
            }
        }

        return(result);
    }
예제 #29
0
    public void Cut()
    {
        // Get original mesh.
        Mesh originalMesh = meshToCut.mesh;

        originalMesh.RecalculateBounds();
        List <MeshPart> parts = new List <MeshPart>();

        // Get the main part of the original mesh.
        MeshPart mainPart = new MeshPart(meshToCut.transform)
        {
            uVs       = originalMesh.uv.ToList(),
            vertices  = originalMesh.vertices.ToList(),
            normals   = originalMesh.normals.ToList(),
            triangles = new List <List <int> > {
                new int[originalMesh.subMeshCount].ToList()
            },
            bounds = originalMesh.bounds
        };

        for (int i = 0; i < originalMesh.subMeshCount; i++)
        {
            mainPart.triangles[i] = originalMesh.GetTriangles(i).ToList();
        }

        // Send our part to GenerateMesh two times, for each side of the plane.
        parts.Add(GenerateMesh(mainPart, collider.bounds, true));
        parts.Add(GenerateMesh(mainPart, collider.bounds, false));

        // Setup a gameobject with our result and apply a force to its parts.
        for (int i = 0; i < parts.Count; i++)
        {
            parts[i].ToGameobject(meshToCut.gameObject);
        }

        Destroy(meshToCut.gameObject);
    }
예제 #30
0
        /// <summary>
        /// Loads vertex data from a mesh given a partitionIndex.
        /// </summary>
        protected bool LoadVertexData(Mesh mesh, int partitionIndex)
        {
            Stride = sizeof(float) * 3;             // 12 bytes

            MeshPart meshPartition = mesh.GetPartition(partitionIndex);
            int      vertexCount   = meshPartition.VertexCount;
            int      startIndex    = meshPartition.StartVertexIndex;
            int      endIndex      = meshPartition.EndVertexIndex;

            int count = endIndex - startIndex;

            var vertices = new VData[count];

            for (int i = startIndex; i < endIndex; i++)
            {
                vertices [i - startIndex].Vertex = mesh.Vertices [i];
            }

            TriangleCount += (uint)mesh.Faces.Count;

            GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(vertices.Length * Stride), vertices, BufferUsage.StaticDraw);

            return(vertices.Length > 0);
        }
예제 #31
0
        //GRAPHICS STUFF: ?something? -> CreateGraphic()
        protected void RebuildGraphic(SmartComponent component)
        {
            GraphicComponent gc = null;

            if (component.GraphicComponents.TryGetGraphicComponent("_sensorPart_", out gc))
            {
                component.GraphicComponents.Remove(gc);
            }

            Part part = new Part(false);

            part.UIVisible      = false;
            part.PickingEnabled = false;
            part.Detectable     = false;
            part.Name           = "_sensorPart_";
            component.GraphicComponents.Add(part);

            MeshPart mp = new MeshPart();

            CreateGraphic(component, mp);
            part.Mesh[DetailLevels.Medium] = mp;
            part.Mesh.Rebuild();
            part.Color = System.Drawing.Color.FromArgb(64, 255, 255, 0);
        }
예제 #32
0
        /// <summary>
        /// Parses the MDL file to obtain model information
        /// </summary>
        /// <param name="selectedItem">The currently selected item</param>
        /// <param name="selectedRace">The currently selected race</param>
        /// <param name="selectedBody">The currently selected body</param>
        /// <param name="selectedPart">The currently selected part</param>
        /// <param name="selectedCategory">The items category </param>
        public MDL(ItemData selectedItem, string selectedCategory, string selectedRace, string selectedBody, string selectedPart)
        {
            string itemType  = Helper.GetCategoryType(selectedCategory);
            string MDLFolder = "";

            if (itemType.Equals("weapon") || itemType.Equals("food"))
            {
                if (selectedPart.Equals("Secondary"))
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.SecondaryModelID, selectedItem.SecondaryModelBody);
                }
                else
                {
                    MDLFolder = string.Format(Strings.WeapMDLFolder, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                    MDLFile   = string.Format(Strings.WeapMDLFile, selectedItem.PrimaryModelID, selectedItem.PrimaryModelBody);
                }
            }
            else if (itemType.Equals("accessory"))
            {
                MDLFolder = string.Format(Strings.AccMDLFolder, selectedItem.PrimaryModelID);
                MDLFile   = string.Format(Strings.AccMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
            }
            else if (itemType.Equals("character"))
            {
                if (selectedItem.ItemName.Equals(Strings.Body))
                {
                    MDLFolder = string.Format(Strings.BodyMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.BodyMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Face))
                {
                    MDLFolder = string.Format(Strings.FaceMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.FaceMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Hair))
                {
                    MDLFolder = string.Format(Strings.HairMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.HairMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
                else if (selectedItem.ItemName.Equals(Strings.Tail))
                {
                    MDLFolder = string.Format(Strings.TailMDLFolder, selectedRace, selectedBody.PadLeft(4, '0'));
                    MDLFile   = string.Format(Strings.TailMDLFile, selectedRace, selectedBody.PadLeft(4, '0'), selectedPart);
                }
            }
            else if (itemType.Equals("monster"))
            {
                bool isDemiHuman = false;
                if (selectedItem.PrimaryMTRLFolder != null)
                {
                    isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");
                }

                string ID   = "";
                string body = "";

                if (selectedCategory.Equals(Strings.Pets))
                {
                    int part = 1;

                    if (selectedItem.ItemName.Equals(Strings.Selene) || selectedItem.ItemName.Equals(Strings.Bishop_Autoturret))
                    {
                        part = 2;
                    }

                    ID   = Info.petID[selectedItem.ItemName];
                    body = part.ToString().PadLeft(4, '0');
                }
                else
                {
                    ID   = selectedItem.PrimaryModelID.PadLeft(4, '0');
                    body = selectedItem.PrimaryModelBody;
                }

                if (isDemiHuman)
                {
                    MDLFolder = string.Format(Strings.DemiMDLFolder, ID, body);
                    MDLFile   = string.Format(Strings.DemiMDLFile, ID, body, selectedPart);
                }
                else
                {
                    MDLFolder = string.Format(Strings.MonsterMDLFolder, ID, body);
                    MDLFile   = string.Format(Strings.MonsterMDLFile, ID, body);
                }
            }
            else
            {
                MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.PrimaryModelID);

                if (selectedPart.Equals("-"))
                {
                    MDLFile = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, Info.slotAbr[selectedCategory]);
                }
                else
                {
                    MDLFile = string.Format(Strings.EquipMDLFile, selectedRace, selectedItem.PrimaryModelID, selectedPart);
                }
            }

            fullPath = MDLFolder + "/" + MDLFile;
            int offset = Helper.GetDataOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile), Strings.ItemsDat);

            if (offset == 0)
            {
                if (itemType.Equals("weapon"))
                {
                    if (selectedPart.Equals("Secondary"))
                    {
                        MDLFolder = string.Format(Strings.EquipMDLFolder, selectedItem.SecondaryModelID);
                        MDLFile   = string.Format(Strings.EquipMDLFile, "0101", selectedItem.SecondaryModelID, Info.slotAbr[Strings.Hands]);

                        offset = Helper.GetDataOffset(FFCRC.GetHash(MDLFolder), FFCRC.GetHash(MDLFile), Strings.ItemsDat);
                    }
                }
            }

            int datNum = ((offset / 8) & 0x000f) / 2;

            var MDLDatData = Helper.GetType3DecompressedData(offset, datNum, Strings.ItemsDat);

            using (BinaryReader br = new BinaryReader(new MemoryStream(MDLDatData.Item1)))
            {
                // The size of the header + (size of the mesh information block (136 bytes) * the number of meshes) + padding
                br.BaseStream.Seek(64 + 136 * MDLDatData.Item2 + 4, SeekOrigin.Begin);

                var modelStringCount = br.ReadInt32();
                var stringBlockSize  = br.ReadInt32();
                var stringBlock      = br.ReadBytes(stringBlockSize);

                var unknown = br.ReadBytes(4);

                var totalMeshCount       = br.ReadInt16();
                var attributeStringCount = br.ReadInt16();
                var meshPartsCount       = br.ReadInt16();
                var materialStringCount  = br.ReadInt16();
                var boneStringCount      = br.ReadInt16();
                var boneListCount        = br.ReadInt16();

                var unknown1 = br.ReadInt16();
                var unknown2 = br.ReadInt16();
                var unknown3 = br.ReadInt16();
                var unknown4 = br.ReadInt16();
                var unknown5 = br.ReadInt16();
                var unknown6 = br.ReadInt16();

                br.ReadBytes(10);

                var unknown7 = br.ReadInt16();

                br.ReadBytes(16);

                using (BinaryReader br1 = new BinaryReader(new MemoryStream(stringBlock)))
                {
                    br1.BaseStream.Seek(0, SeekOrigin.Begin);

                    for (int i = 0; i < attributeStringCount; i++)
                    {
                        while (br1.ReadByte() != 0)
                        {
                            //extract each atribute string here
                        }
                    }

                    for (int i = 0; i < boneStringCount; i++)
                    {
                        byte        b;
                        List <byte> boneName = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            boneName.Add(b);
                        }
                        string bone = Encoding.ASCII.GetString(boneName.ToArray());
                        bone = bone.Replace("\0", "");

                        boneStrings.Add(bone);
                    }

                    for (int i = 0; i < materialStringCount; i++)
                    {
                        byte        b;
                        List <byte> name = new List <byte>();
                        while ((b = br1.ReadByte()) != 0)
                        {
                            name.Add(b);
                        }
                        string material = Encoding.ASCII.GetString(name.ToArray());
                        material = material.Replace("\0", "");

                        materialStrings.Add(material);
                    }
                }

                br.ReadBytes(32 * unknown5);

                for (int i = 0; i < 3; i++)
                {
                    LevelOfDetail LoD = new LevelOfDetail();
                    LoD.MeshOffset = br.ReadInt16();
                    LoD.MeshCount  = br.ReadInt16();

                    br.ReadBytes(40);

                    LoD.VertexDataSize = br.ReadInt32();
                    LoD.IndexDataSize  = br.ReadInt32();
                    LoD.VertexOffset   = br.ReadInt32();
                    LoD.IndexOffset    = br.ReadInt32();

                    modelData.LoD.Add(LoD);
                }

                var savePos = br.BaseStream.Position;

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    List <MeshDataInfo> meshInfoList = new List <MeshDataInfo>();

                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        modelData.LoD[i].MeshList.Add(new Mesh());
                        meshInfoList.Clear();

                        br.BaseStream.Seek((i * 136) + 68, SeekOrigin.Begin);
                        var dataBlockNum = br.ReadByte();

                        while (dataBlockNum != 255)
                        {
                            MeshDataInfo meshInfo = new MeshDataInfo()
                            {
                                VertexDataBlock = dataBlockNum,
                                Offset          = br.ReadByte(),
                                DataType        = br.ReadByte(),
                                UseType         = br.ReadByte()
                            };

                            meshInfoList.Add(meshInfo);

                            br.ReadBytes(4);

                            dataBlockNum = br.ReadByte();
                        }

                        modelData.LoD[i].MeshList[j].MeshDataInfoList = meshInfoList.ToArray();
                    }
                }

                br.BaseStream.Seek(savePos, SeekOrigin.Begin);

                for (int x = 0; x < modelData.LoD.Count; x++)
                {
                    for (int i = 0; i < modelData.LoD[x].MeshCount; i++)
                    {
                        MeshInfo meshInfo = new MeshInfo()
                        {
                            VertexCount     = br.ReadInt32(),
                            IndexCount      = br.ReadInt32(),
                            MaterialNum     = br.ReadInt16(),
                            MeshPartOffset  = br.ReadInt16(),
                            MeshPartCount   = br.ReadInt16(),
                            BoneListIndex   = br.ReadInt16(),
                            IndexDataOffset = br.ReadInt32()
                        };

                        for (int j = 0; j < 3; j++)
                        {
                            meshInfo.VertexDataOffsets.Add(br.ReadInt32());
                        }

                        for (int k = 0; k < 3; k++)
                        {
                            meshInfo.VertexSizes.Add(br.ReadByte());
                        }

                        meshInfo.VertexDataBlockCount = br.ReadByte();

                        modelData.LoD[x].MeshList[i].MeshInfo = meshInfo;
                    }
                }

                br.ReadBytes(attributeStringCount * 4);
                br.ReadBytes(unknown6 * 20);

                for (int i = 0; i < modelData.LoD.Count; i++)
                {
                    foreach (var mesh in modelData.LoD[i].MeshList)
                    {
                        for (int j = 0; j < mesh.MeshInfo.MeshPartCount; j++)
                        {
                            MeshPart meshPart = new MeshPart()
                            {
                                IndexOffset = br.ReadInt32(),
                                IndexCount  = br.ReadInt32(),
                                Attributes  = br.ReadInt32(),
                                BoneOffset  = br.ReadInt16(),
                                BoneCount   = br.ReadInt16()
                            };

                            mesh.MeshPartList.Add(meshPart);
                        }
                    }
                }

                br.ReadBytes(unknown7 * 12);
                br.ReadBytes(materialStringCount * 4);
                br.ReadBytes(boneStringCount * 4);

                for (int i = 0; i < boneListCount; i++)
                {
                    Bones bones = new Bones();

                    for (int j = 0; j < 64; j++)
                    {
                        bones.BoneData.Add(br.ReadInt16());
                    }

                    bones.BoneCount = br.ReadInt32();

                    modelData.BoneSet.Add(bones);
                }

                //br.ReadBytes(unknown1 * 16);

                Dictionary <int, int>         indexMin     = new Dictionary <int, int>();
                Dictionary <int, List <int> > extraIndices = new Dictionary <int, List <int> >();
                List <ExtraIndex>             indexCounts  = new List <ExtraIndex>();

                var pCount  = 0;
                var pCount1 = 0;
                var pCount2 = 0;

                if (unknown1 > 0)
                {
                    for (int i = 0; i < unknown1; i++)
                    {
                        //not sure
                        br.ReadBytes(4);

                        //LoD[0] Extra Data Index
                        var p1 = br.ReadUInt16();

                        //LoD[1] Extra Data Index
                        var p2 = br.ReadUInt16();

                        //LoD[2] Extra Data Index
                        var p3 = br.ReadUInt16();


                        //LoD[0] Extra Data Part Count
                        var p1n = br.ReadUInt16();
                        pCount += p1n;

                        //LoD[1] Extra Data Part Count
                        var p2n = br.ReadUInt16();
                        pCount1 += p2n;

                        //LoD[2] Extra Data Part Count
                        var p3n = br.ReadUInt16();
                        pCount2 += p3n;
                    }
                }

                Dictionary <int, int> indexLoc = new Dictionary <int, int>();

                if (unknown1 > 0)
                {
                    for (int i = 0; i < modelData.LoD[0].MeshCount; i++)
                    {
                        var ido = modelData.LoD[0].MeshList[i].MeshInfo.IndexDataOffset;
                        indexLoc.Add(ido, i);
                    }
                }


                List <int>            maskCounts       = new List <int>();
                Dictionary <int, int> totalExtraCounts = new Dictionary <int, int>();
                if (unknown2 > 0)
                {
                    for (int i = 0; i < pCount; i++)
                    {
                        //Index Offset Start
                        var m1   = br.ReadInt32();
                        var iLoc = 0;
                        if (indexLoc.ContainsKey(m1))
                        {
                            iLoc = indexLoc[m1];
                        }

                        //index count
                        var mCount = br.ReadInt32();

                        //index offset in unk3
                        var mOffset = br.ReadInt32();

                        indexCounts.Add(new ExtraIndex()
                        {
                            IndexLocation = iLoc, IndexCount = mCount
                        });
                        maskCounts.Add(mCount);
                    }

                    br.ReadBytes((pCount1 + pCount2) * 12);
                }

                int totalLoD0MaskCount = 0;

                if (unknown2 > 0)
                {
                    for (int i = 0; i < pCount; i++)
                    {
                        totalLoD0MaskCount += maskCounts[i];
                    }
                }

                if (unknown3 > 0)
                {
                    var unk3Remainder = (unknown3 * 4) - (totalLoD0MaskCount * 4);

                    foreach (var ic in indexCounts)
                    {
                        HashSet <int> mIndexList = new HashSet <int>();

                        for (int i = 0; i < ic.IndexCount; i++)
                        {
                            //index its replacing? attatched to?
                            br.ReadBytes(2);
                            //extra index following last equipment index
                            var mIndex = br.ReadInt16();
                            mIndexList.Add(mIndex);

                            if (extraIndices.ContainsKey(ic.IndexLocation))
                            {
                                extraIndices[ic.IndexLocation].Add(mIndex);
                            }
                            else
                            {
                                extraIndices.Add(ic.IndexLocation, new List <int>()
                                {
                                    mIndex
                                });
                            }
                        }

                        if (totalExtraCounts.ContainsKey(ic.IndexLocation))
                        {
                            totalExtraCounts[ic.IndexLocation] += mIndexList.Count;
                        }
                        else
                        {
                            totalExtraCounts.Add(ic.IndexLocation, mIndexList.Count);
                        }
                    }
                    //the rest of unk3
                    br.ReadBytes(unk3Remainder);
                }



                if (unknown3 > 0)
                {
                    foreach (var ei in extraIndices)
                    {
                        indexMin.Add(ei.Key, ei.Value.Min());
                    }

                    extraIndexData.indexCounts      = indexCounts;
                    extraIndexData.indexMin         = indexMin;
                    extraIndexData.totalExtraCounts = totalExtraCounts;
                    extraIndexData.extraIndices     = extraIndices;

                    modelData.ExtraData = extraIndexData;
                }

                //br.ReadBytes(unknown3 * 4);

                var boneIndexSize = br.ReadInt32();

                for (int i = 0; i < boneIndexSize / 2; i++)
                {
                    modelData.BoneIndicies.Add(br.ReadInt16());
                }

                int padding = br.ReadByte();
                br.ReadBytes(padding);

                for (int i = 0; i < 4; i++)
                {
                    ModelMaterial.BoundingBox boundingBox = new ModelMaterial.BoundingBox();
                    for (int j = 0; j < 4; j++)
                    {
                        boundingBox.PointA.Add(br.ReadSingle());
                    }
                    for (int k = 0; k < 4; k++)
                    {
                        boundingBox.PointB.Add(br.ReadSingle());
                    }

                    modelData.BoundingBoxes.Add(boundingBox);
                }

                //float4x4
                for (int i = 0; i < boneStringCount; i++)
                {
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());

                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                    boneTransforms.Add(br.ReadSingle());
                }

                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < modelData.LoD[i].MeshCount; j++)
                    {
                        Mesh mesh = modelData.LoD[i].MeshList[j];

                        for (int k = 0; k < mesh.MeshInfo.VertexDataBlockCount; k++)
                        {
                            br.BaseStream.Seek(modelData.LoD[i].VertexOffset + mesh.MeshInfo.VertexDataOffsets[k], SeekOrigin.Begin);

                            mesh.MeshVertexData.Add(br.ReadBytes(mesh.MeshInfo.VertexSizes[k] * mesh.MeshInfo.VertexCount));
                        }

                        br.BaseStream.Seek(modelData.LoD[i].IndexOffset + (mesh.MeshInfo.IndexDataOffset * 2), SeekOrigin.Begin);

                        mesh.IndexData = br.ReadBytes(2 * mesh.MeshInfo.IndexCount);
                    }
                }

                int vertex = 0, coordinates = 0, normals = 0, tangents = 0, colors = 0, blendWeights = 0, blendIndices = 0;

                for (int i = 0; i < modelData.LoD[0].MeshCount; i++)
                {
                    objBytes.Clear();

                    var vertexList        = new Vector3Collection();
                    var texCoordList      = new Vector2Collection();
                    var texCoordList2     = new Vector2Collection();
                    var normalList        = new Vector3Collection();
                    var tangentList       = new Vector3Collection();
                    var colorsList        = new Color4Collection();
                    var indexList         = new IntCollection();
                    var blendWeightList   = new List <float>();
                    var blendWeightList2  = new List <float[]>();
                    var blendIndicesList  = new List <int>();
                    var blendIndicesList2 = new List <int[]>();
                    var weightCounts      = new List <int>();


                    Mesh mesh = modelData.LoD[0].MeshList[i];

                    MeshDataInfo[] meshDataInfoList = mesh.MeshDataInfoList;

                    int c = 0;
                    foreach (var meshDataInfo in meshDataInfoList)
                    {
                        if (meshDataInfo.UseType == 0)
                        {
                            vertex = c;
                        }
                        else if (meshDataInfo.UseType == 1)
                        {
                            blendWeights = c;
                        }
                        else if (meshDataInfo.UseType == 2)
                        {
                            blendIndices = c;
                        }
                        else if (meshDataInfo.UseType == 3)
                        {
                            normals = c;
                        }
                        else if (meshDataInfo.UseType == 4)
                        {
                            coordinates = c;
                        }
                        else if (meshDataInfo.UseType == 6)
                        {
                            tangents = c;
                        }
                        else if (meshDataInfo.UseType == 7)
                        {
                            colors = c;
                        }

                        c++;
                    }

                    /*
                     * -----------------
                     * Vertex
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[vertex].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[vertex].VertexDataBlock] + meshDataInfoList[vertex].Offset, SeekOrigin.Begin);

                            Vector3 vVector = new Vector3();
                            if (meshDataInfoList[vertex].DataType == 13 || meshDataInfoList[vertex].DataType == 14)
                            {
                                System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h3 = System.Half.ToHalf((ushort)br1.ReadInt16());

                                float x = HalfHelper.HalfToSingle(h1);
                                float y = HalfHelper.HalfToSingle(h2);
                                float z = HalfHelper.HalfToSingle(h3);

                                vVector = new Vector3(x, y, z);
                                objBytes.Add("v " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            }
                            else if (meshDataInfoList[vertex].DataType == 2)
                            {
                                var x = BitConverter.ToSingle(br1.ReadBytes(4), 0);
                                var y = BitConverter.ToSingle(br1.ReadBytes(4), 0);
                                var z = BitConverter.ToSingle(br1.ReadBytes(4), 0);

                                vVector = new Vector3(x, y, z);
                                objBytes.Add("v " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            }

                            vertexList.Add(vVector);
                        }
                    }


                    /*
                     * -----------------
                     * Blend Weight
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[blendWeights].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[blendWeights].VertexDataBlock] + meshDataInfoList[blendWeights].Offset, SeekOrigin.Begin);

                            float x = br1.ReadByte() / 255.0f;
                            float y = br1.ReadByte() / 255.0f;
                            float z = br1.ReadByte() / 255.0f;
                            float w = br1.ReadByte() / 255.0f;

                            int count = 0;
                            if (x != 0)
                            {
                                blendWeightList.Add(x);
                                count++;

                                if (y != 0)
                                {
                                    blendWeightList.Add(y);
                                    count++;

                                    if (z != 0)
                                    {
                                        blendWeightList.Add(z);
                                        count++;

                                        if (w != 0)
                                        {
                                            blendWeightList.Add(w);
                                            count++;
                                        }
                                    }
                                }
                            }

                            if (count == 1)
                            {
                                blendWeightList2.Add(new float[] { x });
                            }
                            else if (count == 2)
                            {
                                blendWeightList2.Add(new float[] { x, y });
                            }
                            else if (count == 3)
                            {
                                blendWeightList2.Add(new float[] { x, y, z });
                            }
                            else if (count == 4)
                            {
                                blendWeightList2.Add(new float[] { x, y, z, w });
                            }

                            weightCounts.Add(count);
                        }
                    }


                    /*
                     * -----------------
                     * Blend Index
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[blendIndices].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[blendIndices].VertexDataBlock] + meshDataInfoList[blendIndices].Offset, SeekOrigin.Begin);

                            int x = br1.ReadByte();
                            int y = br1.ReadByte();
                            int z = br1.ReadByte();
                            int w = br1.ReadByte();

                            if (weightCounts[j] == 1)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList2.Add(new int[] { x });
                            }
                            else if (weightCounts[j] == 2)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList2.Add(new int[] { x, y });
                            }
                            else if (weightCounts[j] == 3)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList.Add(z);
                                blendIndicesList2.Add(new int[] { x, y, z });
                            }
                            else if (weightCounts[j] == 4)
                            {
                                blendIndicesList.Add(x);
                                blendIndicesList.Add(y);
                                blendIndicesList.Add(z);
                                blendIndicesList.Add(w);
                                blendIndicesList2.Add(new int[] { x, y, z, w });
                            }
                        }
                    }


                    /*
                     * -----------------
                     * Texture Coordinates
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[coordinates].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[coordinates].VertexDataBlock] + meshDataInfoList[coordinates].Offset, SeekOrigin.Begin);

                            float x = 0;
                            float y = 0;
                            float z = 0;
                            float w = 0;
                            if (meshDataInfoList[coordinates].DataType == 13 || meshDataInfoList[coordinates].DataType == 14)
                            {
                                var sx = (ushort)br1.ReadInt16();
                                var sy = (ushort)br1.ReadInt16();
                                var sz = (ushort)br1.ReadInt16();
                                var sw = (ushort)br1.ReadInt16();

                                var h1 = new SharpDX.Half(sx);
                                var h2 = new SharpDX.Half(sy);
                                var h3 = new SharpDX.Half(sz);
                                var h4 = new SharpDX.Half(sw);

                                x = h1;
                                y = h2;
                                z = h3;
                                w = h4;
                            }
                            else if (meshDataInfoList[coordinates].DataType == 1)
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                            }
                            else
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                                z = br1.ReadSingle();
                                w = br1.ReadSingle();
                            }


                            var ox = x - Math.Truncate(x);
                            var oy = y - Math.Truncate(y);

                            objBytes.Add("vt " + ox.ToString("N5") + " " + (1 - y).ToString("N5") + " ");
                            texCoordList.Add(new Vector2(x, y));
                            texCoordList2.Add(new Vector2(z, w));
                        }
                    }



                    /*
                     * -----------------
                     * Normals
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[normals].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[normals].VertexDataBlock] + meshDataInfoList[normals].Offset, SeekOrigin.Begin);

                            float x = 0;
                            float y = 0;
                            float z = 0;
                            float w = 0;

                            if (meshDataInfoList[normals].DataType == 13 || meshDataInfoList[normals].DataType == 14)
                            {
                                System.Half h1 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h2 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h3 = System.Half.ToHalf((ushort)br1.ReadInt16());
                                System.Half h4 = System.Half.ToHalf((ushort)br1.ReadInt16());

                                x = HalfHelper.HalfToSingle(h1);
                                y = HalfHelper.HalfToSingle(h2);
                                z = HalfHelper.HalfToSingle(h3);
                                w = HalfHelper.HalfToSingle(h4);
                            }
                            else
                            {
                                x = br1.ReadSingle();
                                y = br1.ReadSingle();
                                z = br1.ReadSingle();
                            }

                            var nv = new Vector3(x, y, z);

                            objBytes.Add("vn " + x.ToString("N5") + " " + y.ToString("N5") + " " + z.ToString("N5") + " ");
                            normalList.Add(nv);
                        }
                    }


                    /*
                     * -----------------
                     * Tangents
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[tangents].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[tangents].VertexDataBlock] + meshDataInfoList[tangents].Offset, SeekOrigin.Begin);

                            int x = br1.ReadByte();
                            int y = br1.ReadByte();
                            int z = br1.ReadByte();
                            int w = br1.ReadByte();

                            var x1 = x * 2 / 255f - 1f;
                            var y1 = y * 2 / 255f - 1f;
                            var z1 = z * 2 / 255f - 1f;
                            var w1 = w * 2 / 255f - 1f;


                            var nv = new Vector3(x1, y1, z1);

                            tangentList.Add(nv);
                        }
                    }


                    /*
                     * -----------------
                     * Vertex Color
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.MeshVertexData[meshDataInfoList[colors].VertexDataBlock])))
                    {
                        for (int j = 0; j < mesh.MeshInfo.VertexCount; j++)
                        {
                            br1.BaseStream.Seek(j * mesh.MeshInfo.VertexSizes[meshDataInfoList[colors].VertexDataBlock] + meshDataInfoList[colors].Offset, SeekOrigin.Begin);

                            int a = br1.ReadByte();
                            int r = br1.ReadByte();
                            int g = br1.ReadByte();
                            int b = br1.ReadByte();

                            colorsList.Add(new Color4(r, g, b, a));
                        }
                    }


                    /*
                     * -----------------
                     * Index
                     * -----------------
                     */
                    using (BinaryReader br1 = new BinaryReader(new MemoryStream(mesh.IndexData)))
                    {
                        for (int j = 0; j < mesh.MeshInfo.IndexCount; j += 3)
                        {
                            int i1 = br1.ReadInt16();
                            int i2 = br1.ReadInt16();
                            int i3 = br1.ReadInt16();

                            objBytes.Add("f " + (i1 + 1) + "/" + (i1 + 1) + "/" + (i1 + 1) + " " + (i2 + 1) + "/" + (i2 + 1) + "/" + (i2 + 1) + " " + (i3 + 1) + "/" + (i3 + 1) + "/" + (i3 + 1) + " ");

                            indexList.Add(i1);
                            indexList.Add(i2);
                            indexList.Add(i3);
                        }
                    }

                    ModelMeshData modelMeshData = new ModelMeshData()
                    {
                        Vertices              = vertexList,
                        Normals               = normalList,
                        TextureCoordinates    = texCoordList,
                        TextureCoordinates2   = texCoordList2,
                        BiTangents            = tangentList,
                        Indices               = indexList,
                        VertexColors          = colorsList,
                        OBJFileData           = objBytes.ToArray(),
                        BoneStrings           = boneStrings,
                        BoneIndices           = modelData.BoneIndicies,
                        BoneTransforms        = boneTransforms,
                        BlendWeights          = blendWeightList,
                        BlendIndices          = blendIndicesList,
                        WeightCounts          = weightCounts,
                        MeshPartList          = mesh.MeshPartList,
                        BlendIndicesArrayList = blendIndicesList2,
                        BlendWeightsArrayList = blendWeightList2,
                        MaterialNum           = mesh.MeshInfo.MaterialNum,
                        MeshPartCount         = mesh.MeshInfo.MeshPartCount,
                        MeshPartOffset        = mesh.MeshInfo.MeshPartOffset
                    };

                    meshList.Add(modelMeshData);
                }
            }
        }
예제 #33
0
        public override void DrawSubObjekt(RenderInformation RI, MeshPart M2, GraphicNode GN)
        {
            ILrentObject O = (GN.Tag as ILrentObject.ObjectTagger).Object;
            Vector4[] buffer = null;
            if (O.getSet<gIPath>() != null)
                buffer = O.getSet<gIPath>().getBuffer();
            else buffer = O.getSet<gIZone>().getBuffer();

            if (buffer == null || buffer.Length > 100) return;

            E.Variables["ColorA"].SetVariable(V);
            E.Variables["WVP"].SetVariable(O.Matrix * RI.ViewMatrix * RI.ProjectionMatrix);
            E.Variables["PointA"].SetVariable(buffer);
            INavBase b = (GN.Tag as ILrentObject.ObjectTagger).Object.getSet<INavBase>();
            mBuffer.DrawBufferNonIndexed(E.Techniques[0].Passes[0], buffer.Length, b is gIPath ? PrimitiveTopology.TriangleList : PrimitiveTopology.LineList);
        }
예제 #34
0
		private static bool SweptTest(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref Vector3 delta)
		{
			CollisionInfo cur = new CollisionInfo(), final = new CollisionInfo() { Depth = float.MaxValue };
			Vector3 v;
			float d, dx, curTime, finalTime = 0f, tlast = float.MaxValue;

			// axis: face normal of B
			cur.Normal = tri.Normal;
			Vector3.Negate(ref cur.Normal, out cur.NormalNeg);
			cur.FeatureA = a.ExtremeVertex(ref cur.NormalNeg);
			cur.FeatureA.X = -cur.FeatureA.X;
			cur.FeatureB.Type = TriangleFeatureType.Face;
			Vector3.Dot(ref cur.Normal, ref tri.V1, out cur.FeatureB.X);
			cur.Depth = cur.FeatureB.X - cur.FeatureA.X;
			Vector3.Dot(ref cur.Normal, ref delta, out dx);
			curTime = cur.Depth / dx;

			final = cur;
			if (cur.Depth >= 0f)
			{
				if (dx > 0f)
					tlast = curTime;
			}
			else
			{
				if (dx >= 0f || curTime > 1f)
					return false;
				finalTime = curTime;
			}

			// axes: face normals of A
			for (int i = 0; i < a.FaceCount; i++)
			{
				a.FaceNormal(i, out cur.NormalNeg);
				Vector3.Negate(ref cur.NormalNeg, out cur.Normal);
				a.World(a.Face(i)[0], out v);
				cur.FeatureA = new PolyhedronFeature(PolyhedronFeatureType.Face, i, 0f);
				Vector3.Dot(ref cur.Normal, ref v, out cur.FeatureA.X);
				cur.FeatureB = tri.ExtremeVertex(ref cur.Normal);
				cur.Depth = cur.FeatureB.X - cur.FeatureA.X;
				Vector3.Dot(ref cur.Normal, ref delta, out dx);
				curTime = cur.Depth / dx;

				if (cur.Depth >= 0f)
				{
					if (finalTime <= 0f && cur.Depth < final.Depth)
					{
						final = cur;
						finalTime = 0f;
					}
					if (dx > 0f && curTime < tlast)
						tlast = curTime;
				}
				else
				{
					if (dx >= 0f || curTime > 1f)
						return false;
					if (curTime > finalTime)
					{
						final = cur;
						finalTime = curTime;
					}
				} 
			}

			// crossed edges from A and B
			Vector3 centerA, centerB;
			a.Center(out centerA);
			tri.Center(out centerB);
			for (int i = 0; i < a.EdgeVectorCount; i++)
			{
				for (int j = 1; j <= 3; j++)
				{
					// calculate normal from the two edge vectors
					Vector3 eva, evb;
					a.EdgeVector(i, out eva);
					tri.EdgeVector(j, out evb);
					Vector3.Cross(ref eva, ref evb, out cur.Normal);
					if (cur.Normal.LengthSquared() < Constants.Epsilon)
						continue;
					cur.Normal.Normalize();

					float ca, cb;
					Vector3.Dot(ref cur.Normal, ref centerA, out ca);
					Vector3.Dot(ref cur.Normal, ref centerB, out cb);
					if (ca < cb)
					{
						cur.NormalNeg = cur.Normal;
						Vector3.Negate(ref cur.NormalNeg, out cur.Normal);
					}
					else
						Vector3.Negate(ref cur.Normal, out cur.NormalNeg);

					// skip this normal if it's close to one we already have
					Vector3.Dot(ref cur.Normal, ref final.Normal, out d);
					if (Math.Abs(1f - d) < Constants.Epsilon)
						continue;

					cur.FeatureA = a.ExtremeVertex(ref cur.NormalNeg);
					cur.FeatureA.X = -cur.FeatureA.X;
					cur.FeatureB = tri.ExtremeVertex(ref cur.Normal);
					cur.Depth = cur.FeatureB.X - cur.FeatureA.X;
					Vector3.Dot(ref cur.Normal, ref delta, out dx);
					curTime = cur.Depth / dx;

					if (cur.Depth >= 0f)
					{
						if (finalTime <= 0f && cur.Depth < final.Depth)
						{
							final = cur;
							finalTime = 0f;
						}
						if (dx > 0f && curTime < tlast)
							tlast = curTime;
					}
					else
					{
						if (dx >= 0f || curTime > 1f)
							return false;
						if (curTime > finalTime)
						{
							final = cur;
							finalTime = curTime;
						}
					}
				}
			}

			if (finalTime >= tlast)
				return false;

			Vector3.Dot(ref final.Normal, ref delta, out dx);
			if (finalTime <= 0f)
				dx = 0f;

			if (final.FeatureA.Type == PolyhedronFeatureType.Vertex)
			{
				final.FeatureA = a.ExtremeFeature(ref final.NormalNeg, dx - final.FeatureB.X);
				final.FeatureA.X = -final.FeatureA.X;
			}
			if (final.FeatureB.Type == TriangleFeatureType.Vertex)
			{
				final.FeatureB = tri.ExtremeFeature(ref final.Normal, dx + final.FeatureA.X);
			}

			// make sure the normal points outward
			Vector3.Dot(ref tri.Normal, ref final.Normal, out d);
			if (d < 0f)
			{
				Vector3.Multiply(ref tri.Normal, -2f * d, out v);
				Vector3.Add(ref final.Normal, ref v, out final.Normal);
			}

			CalculateContactPoints(cf, a, b, ref tri, ref final);
			return true;
		}
예제 #35
0
			public void Initialize(CollisionFunctor cf, PolyhedronPart a, MeshPart b, Vector3 delta)
			{
				_cf = cf;
				_a = a;
				_b = b;
				_delta = delta;
				_useSweptTest = _delta != Vector3.Zero;
				Depth = float.MaxValue;
				a.Center(out _center);

				// transform bounding box to body space
				b.BoundingBox(out BoundingBox);
				AlignedBox.Transform(ref BoundingBox, ref b.TransformInverse, out BoundingBox);
			}
예제 #36
0
		private static void CalculateEdgeFacePoints(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref CollisionInfo ci)
		{
			Vector3 pa, pb;
			Segment ea, eb, eab;

			int[] edge = a.Edge(ci.FeatureA.Index);
			a.World(edge[0], out ea.P1);
			a.World(edge[1], out ea.P2);
			Plane planeB = new Plane(tri.V1, tri.Normal);
			planeB.ClosestPointTo(ref ea.P1, out eab.P1);
			planeB.ClosestPointTo(ref ea.P2, out eab.P2);

			int count = 0;
			if (tri.Contains(ref eab.P1))
			{
				count++;
				cf.WritePoint(ref ea.P1, ref eab.P1, ref ci.Normal);
			}
			if (tri.Contains(ref eab.P2))
			{
				count++;
				cf.WritePoint(ref ea.P2, ref eab.P2, ref ci.Normal);
			}

			for (int i = 1; i <= 3 && count < 2; i++)
			{
				tri.Edge(i, out eb);
				float sa, sb;
				Segment.ClosestPoints(ref ea, ref eb, out sa, out pa, out sb, out pb);
				if (sa > 0f && sa < 1f && sb > 0f && sb < 1f)
				{
					count++;
					cf.WritePoint(ref pa, ref pb, ref ci.Normal);
				}
			}
		}
예제 #37
0
		private static void CalculateContactPoints(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref CollisionInfo ci)
		{
			if (ci.FeatureB.Type == TriangleFeatureType.Vertex)
			{
				if (ci.FeatureA.Type == PolyhedronFeatureType.Vertex)
					CalculateVertexVertexPoint(cf, a, b, ref tri, ref ci);
				else if (ci.FeatureA.Type == PolyhedronFeatureType.Edge)
					CalculateEdgeVertexPoint(cf, a, b, ref tri, ref ci);
				else if (ci.FeatureA.Type == PolyhedronFeatureType.Face)
					CalculateFaceVertexPoint(cf, a, b, ref tri, ref ci);
			}
			else if (ci.FeatureB.Type == TriangleFeatureType.Edge)
			{
				if (ci.FeatureA.Type == PolyhedronFeatureType.Vertex)
					CalculateVertexEdgePoint(cf, a, b, ref tri, ref ci);
				else if (ci.FeatureA.Type == PolyhedronFeatureType.Edge)
					CalculateEdgeEdgePoints(cf, a, b, ref tri, ref ci);
				else if (ci.FeatureA.Type == PolyhedronFeatureType.Face)
					CalculateFaceEdgePoints(cf, a, b, ref tri, ref ci);
			}
			else if (ci.FeatureB.Type == TriangleFeatureType.Face)
			{
				if (ci.FeatureA.Type == PolyhedronFeatureType.Vertex)
					CalculateVertexFacePoint(cf, a, b, ref tri, ref ci);
				else if (ci.FeatureA.Type == PolyhedronFeatureType.Edge)
					CalculateEdgeFacePoints(cf, a, b, ref tri, ref ci);
				else if (ci.FeatureA.Type == PolyhedronFeatureType.Face)
					CalculateFaceFacePoints(cf, a, b, ref tri, ref ci);
			}
		}
예제 #38
0
		private static void OverlapTest(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri)
		{
			CollisionInfo cur = new CollisionInfo(), final;
			Vector3 v;
			float d;

			// axis: face normal of B
			cur.Normal = tri.Normal;
			Vector3.Negate(ref cur.Normal, out cur.NormalNeg);
			cur.FeatureA = a.ExtremeVertex(ref cur.NormalNeg);
			cur.FeatureA.X = -cur.FeatureA.X;
			cur.FeatureB.Type = TriangleFeatureType.Face;
			Vector3.Dot(ref cur.Normal, ref tri.V1, out cur.FeatureB.X);
			cur.Depth = cur.FeatureB.X - cur.FeatureA.X;
			if (cur.Depth <= -Constants.Epsilon)
				return;
			final = cur;

			// axes: face normals of A
			for (int i = 0; i < a.FaceCount; i++)
			{
				a.FaceNormal(i, out cur.NormalNeg);
				Vector3.Negate(ref cur.NormalNeg, out cur.Normal);
				a.World(a.Face(i)[0], out v);
				cur.FeatureA = new PolyhedronFeature(PolyhedronFeatureType.Face, i, 0f);
				Vector3.Dot(ref cur.Normal, ref v, out cur.FeatureA.X);
				cur.FeatureB = tri.ExtremeVertex(ref cur.Normal);
				cur.Depth = cur.FeatureB.X - cur.FeatureA.X;

				if (cur.Depth <= -Constants.Epsilon)
					return;
				else if (cur.Depth < final.Depth)
					final = cur;
			}

			// crossed edges from A and B
			Vector3 centerA, centerB;
			a.Center(out centerA);
			tri.Center(out centerB);
			for (int i = 0; i < a.EdgeVectorCount; i++)
			{
				for (int j = 1; j <= 3; j++)
				{
					// calculate normal from the two edge vectors
					Vector3 eva, evb;
					a.EdgeVector(i, out eva);
					tri.EdgeVector(j, out evb);
					Vector3.Cross(ref eva, ref evb, out cur.Normal);
					if (cur.Normal.LengthSquared() < Constants.Epsilon)
						continue;
					cur.Normal.Normalize();

					float ca, cb;
					Vector3.Dot(ref cur.Normal, ref centerA, out ca);
					Vector3.Dot(ref cur.Normal, ref centerB, out cb);
					if (ca < cb)
					{
						cur.NormalNeg = cur.Normal;
						Vector3.Negate(ref cur.NormalNeg, out cur.Normal);
					}
					else
						Vector3.Negate(ref cur.Normal, out cur.NormalNeg);

					// skip this normal if it's close to one we already have
					Vector3.Dot(ref cur.Normal, ref final.Normal, out d);
					if (Math.Abs(1f - d) < Constants.Epsilon)
						continue;

					cur.FeatureA = a.ExtremeVertex(ref cur.NormalNeg);
					cur.FeatureA.X = -cur.FeatureA.X;
					cur.FeatureB = tri.ExtremeVertex(ref cur.Normal);
					cur.Depth = cur.FeatureB.X - cur.FeatureA.X;

					if (cur.Depth <= -Constants.Epsilon)
						return;
					else if (final.Depth - cur.Depth >= Constants.Epsilon)
						final = cur;
				}
			}

			if (final.FeatureA.Type == PolyhedronFeatureType.Vertex)
			{
				final.FeatureA = a.ExtremeFeature(ref final.NormalNeg, -final.FeatureB.X);
				final.FeatureA.X = -final.FeatureA.X;
			}
			if (final.FeatureB.Type == TriangleFeatureType.Vertex)
			{
				final.FeatureB = tri.ExtremeFeature(ref final.Normal, final.FeatureA.X);
			}

			// make sure the normal points outward
			Vector3.Dot(ref tri.Normal, ref final.Normal, out d);
			if (d < 0f)
			{
				Vector3.Multiply(ref tri.Normal, -2f * d, out v);
				Vector3.Add(ref final.Normal, ref v, out final.Normal);
			}

			CalculateContactPoints(cf, a, b, ref tri, ref final);
		}
 public ContentMeshPart(ContentMesh mesh, MeshPart basePart)
 {
     this.Mesh = mesh;
     this.BasePart = basePart;
 }
예제 #40
0
        /// <summary>
        /// Creates a default material fitting the given model mesh part
        /// </summary>
        /// <param name="meshPart"></param>
        /// <param name="graphicsDevice"></param>
        /// <returns></returns>
        public static EffectMaterial CreateDefaultMaterial(MeshPart meshPart, GraphicsDevice graphicsDevice)
        {
            BasicEffect effect = new BasicEffect(graphicsDevice);
            Dictionary<String,Object> effectParameters = new Dictionary<string,object>();
            Material material = new Material();

            if (meshPart.Vertices.HasElement(VertexElementUsage.Color))
                effect.VertexColorEnabled = true;

            if (meshPart.Vertices.HasElement(VertexElementUsage.Normal))
                effect.EnableDefaultLighting();

            return new EffectMaterial("Default Material", effect, effectParameters, material);
        }
예제 #41
0
		private static void CalculateVertexVertexPoint(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref CollisionInfo ci)
		{
			Vector3 pa, pb;
			a.World(ci.FeatureA.Index, out pa);
			tri.Vertex(ci.FeatureB.Index, out pb);
			cf.WritePoint(ref pa, ref pb, ref ci.Normal);
		}
예제 #42
0
		private static void CalculateEdgeEdgePoints(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref CollisionInfo ci)
		{
			Vector3 pa, pb;
			Segment ea, eb;

			int[] edgeA = a.Edge(ci.FeatureA.Index);
			a.World(edgeA[0], out ea.P1);
			a.World(edgeA[1], out ea.P2);
			tri.Edge(ci.FeatureB.Index, out eb);

			float sa, sb;
			Segment.ClosestPoints(ref ea, ref eb, out sa, out pa, out sb, out pb);
			cf.WritePoint(ref pa, ref pb, ref ci.Normal);
		}
예제 #43
0
        public static Mesh BakePart(Part part, Material material = null)
        {
            Mesh result = null;

            Asset meshAsset    = null;
            Asset textureAsset = null;

            Vector3 scale  = null;
            CFrame  offset = null;

            if (material != null)
            {
                material.LinkedTo     = part;
                material.Transparency = part.Transparency;
                material.Reflectance  = part.Reflectance;
            }

            if (part.Transparency < 1)
            {
                if (part.IsA("MeshPart"))
                {
                    MeshPart meshPart = (MeshPart)part;
                    if (meshPart.MeshID == null)
                    {
                        string partName = meshPart.Name;
                        if (StandardLimbs.ContainsKey(partName))
                        {
                            meshAsset = StandardLimbs[partName];
                        }
                    }
                    else
                    {
                        meshAsset = Asset.GetByAssetId(meshPart.MeshID);
                    }

                    if (meshPart.TextureID != null)
                    {
                        textureAsset = Asset.GetByAssetId(meshPart.TextureID);
                    }

                    scale  = meshPart.Size / meshPart.InitialSize;
                    offset = part.CFrame;
                }
                else
                {
                    offset = part.CFrame;

                    SpecialMesh specialMesh = part.FindFirstChildOfClass <SpecialMesh>();
                    if (specialMesh != null && specialMesh.MeshType == MeshType.FileMesh)
                    {
                        meshAsset = Asset.GetByAssetId(specialMesh.MeshId);
                        scale     = specialMesh.Scale;
                        offset   *= new CFrame(specialMesh.Offset);
                        if (material != null)
                        {
                            textureAsset         = Asset.GetByAssetId(specialMesh.TextureId);
                            material.VertexColor = specialMesh.VertexColor;
                        }
                    }
                    else
                    {
                        DataModelMesh legacy = part.FindFirstChildOfClass <DataModelMesh>();
                        if (legacy != null)
                        {
                            meshAsset = Head.ResolveHeadMeshAsset(legacy);
                            scale     = legacy.Scale;
                            offset   *= new CFrame(legacy.Offset);
                        }
                    }
                }
            }
            else
            {
                // Just give it a blank mesh to eat for now.
                result = new Mesh();
            }

            if (meshAsset != null)
            {
                if (material != null)
                {
                    material.TextureAsset = textureAsset;
                }

                result = FromAsset(meshAsset);
                result.BakeGeometry(scale, offset);
            }

            return(result);
        }
예제 #44
0
		private static void CalculateVertexEdgePoint(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref CollisionInfo ci)
		{
			Vector3 pa, pb;
			Segment eb;
			float sb;

			tri.Edge(ci.FeatureB.Index, out eb);
			a.World(ci.FeatureA.Index, out pa);
			eb.ClosestPointTo(ref pa, out sb, out pb);
			cf.WritePoint(ref pa, ref pb, ref ci.Normal);
		}
예제 #45
0
		private static void CalculateFaceFacePoints(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref CollisionInfo ci)
		{
			int[] faceA = a.Face(ci.FeatureA.Index);
			Vector3 pa, pb, n;

			a.World(faceA[0], out pa);
			a.FaceNormal(ci.FeatureA.Index, out n);
			Plane planeA = new Plane(pa, n);
			Plane planeB = new Plane(tri.V1, tri.Normal);

			// vertices of A contained in face of B
			for (int i = 0; i < faceA.Length; i++)
			{
				a.World(faceA[i], out pa);
				planeB.ClosestPointTo(ref pa, out pb);
				if (tri.Contains(ref pb))
				{
					cf.WritePoint(ref pa, ref pb, ref ci.Normal);
				}
			}

			for (int i = 1; i <= 3; i++)
			{
				tri.Vertex(i, out pb);
				planeA.ClosestPointTo(ref pb, out pa);
				if (a.IsPointOnFace(ci.FeatureA.Index, ref pa, true))
				{
					cf.WritePoint(ref pa, ref pb, ref ci.Normal);
				}
			}

			// intersection of edges from both faces
			Segment ea, eb;
			for (int i = 0; i < faceA.Length; i++)
			{
				a.World(faceA[i == 0 ? faceA.Length - 1 : i - 1], out ea.P1);
				a.World(faceA[i], out ea.P2);

				for (int j = 1; j <= 3; j++)
				{
					tri.Edge(j, out eb);

					float sa, sb;
					Segment.ClosestPoints(ref ea, ref eb, out sa, out pa, out sb, out pb);
					if (sa > 0f && sa < 1f && sb > 0f && sb < 1f)
					{
						cf.WritePoint(ref pa, ref pb, ref ci.Normal);
					}
				}
			}
		}
예제 #46
0
 public void DrawList(MeshPart M, List<GraphicNode> gns)
 {
 }
예제 #47
0
		private static void CalculateFaceEdgePoints(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref CollisionInfo ci)
		{
			Vector3 pa, pb;
			Segment ea, eba, eb;
			int[] faceA = a.Face(ci.FeatureA.Index);
			a.World(faceA[0], out pa);
			Plane planeA = new Plane(pa, ci.Normal);
			tri.Edge(ci.FeatureB.Index, out eb);
			planeA.ClosestPointTo(ref eb.P1, out eba.P1);
			planeA.ClosestPointTo(ref eb.P2, out eba.P2);

			int count = 0;
			if (a.IsPointOnFace(ci.FeatureA.Index, ref eba.P1, true))
			{
				count++;
				cf.WritePoint(ref eba.P1, ref eb.P1, ref ci.Normal);
			}
			if (a.IsPointOnFace(ci.FeatureA.Index, ref eba.P2, true))
			{
				count++;
				cf.WritePoint(ref eba.P2, ref eb.P2, ref ci.Normal);
			}

			for(int i = 0; i < faceA.Length && count < 2; i++)
			{
				a.World(faceA[i == 0 ? faceA.Length - 1 : i - 1], out ea.P1);
				a.World(faceA[i], out ea.P2);

				float sa, sb;
				Segment.ClosestPoints(ref ea, ref eb, out sa, out pa, out sb, out pb);
				if (sa > 0f && sa < 1f && sb > 0f && sb < 1f)
				{
					count++;
					cf.WritePoint(ref pa, ref pb, ref ci.Normal);
				}
			}
		}
예제 #48
0
			public void Initialize(CollisionFunctor cf, SpherePart a, MeshPart b, Vector3 delta)
			{
				_cf = cf;
				_a = a;
				_b = b;
				_radius = a.World.Radius * b.TransformInverse.Scale;
				_radiusSquared = _radius * _radius;

				Vector3.Transform(ref a.World.Center, ref b.TransformInverse.Combined, out _path.P1);
				Vector3.Transform(ref delta, ref b.TransformInverse.Orientation, out delta);
				Vector3.Multiply(ref delta, b.TransformInverse.Scale, out delta);
				Vector3.Add(ref _path.P1, ref delta, out _path.P2);

				AlignedBox.Fit(ref _path.P1, ref _path.P2, out BoundingBox);

				var radius = new Vector3(_radius);
				Vector3.Subtract(ref BoundingBox.Minimum, ref radius, out BoundingBox.Minimum);
				Vector3.Add(ref BoundingBox.Maximum, ref radius, out BoundingBox.Maximum);
			}
예제 #49
0
		private static void CalculateVertexFacePoint(CollisionFunctor cf, PolyhedronPart a, MeshPart b, ref Triangle tri, ref CollisionInfo ci)
		{
			Vector3 pa, pb;

			a.World(ci.FeatureA.Index, out pa);
			var plane = new Plane(tri.V1, ci.Normal);
			plane.ClosestPointTo(ref pa, out pb);
			cf.WritePoint(ref pa, ref pb, ref ci.Normal);
		}
예제 #50
0
 public override void DrawSubObjekt(RenderInformation RI, MeshPart GSO, GraphicNode GN)
 {
 }