Beispiel #1
0
 private static void ExecuteDrawCall(DrawCall call)
 {
     return;
     //Handles.color = call.color;
     //switch (call.type) {
     //	case DrawType.WireCube:
     //		Handles.DrawWireCube((Vector3) call.parameters[0], (Vector3) call.parameters[1]);
     //		break;
     //	case DrawType.Cube:
     //		// TODO implement
     //		//Handles.DrawCube((Vector3) call.parameters[0], (Vector3) call.parameters[1]);
     //		break;
     //	case DrawType.WireSphere:
     //		Handles.DrawWireDisc((Vector3) call.parameters[0], Vector3.up, (float) call.parameters[1]);
     //		Handles.DrawWireDisc((Vector3) call.parameters[0], Vector3.right, (float) call.parameters[1]);
     //		Handles.DrawWireDisc((Vector3) call.parameters[0], new Vector3(1, 0, 1).normalized, (float) call.parameters[1]);
     //		Handles.DrawWireDisc((Vector3) call.parameters[0], Vector3.forward, (float) call.parameters[1]);
     //		Handles.DrawWireDisc((Vector3) call.parameters[0], new Vector3(-1, 0, 1).normalized, (float) call.parameters[1]);
     //		break;
     //	case DrawType.Sphere:
     //		// TODO implement
     //		//Handles.DrawSphere((Vector3) call.parameters[0], (float) call.parameters[1]);
     //		break;
     //	case DrawType.WireMesh:
     //		Graphics.DrawMeshNow((Mesh) call.parameters[0], (Vector3) call.parameters[1], (Quaternion) call.parameters[2]);
     //		break;
     //}
 }
        public void NameColor()
        {
            MDL0Node      model = ((MDL0Node)_resource);
            MDL0GroupNode g     = model._colorGroup;

            if (g != null)
            {
                foreach (MDL0ColorNode v in g.Children)
                {
                    string name = model.Name + "_";
                    if (v._objects.Count > 0)
                    {
                        MDL0ObjectNode o = v._objects[0];
                        name += o.Name;
                        if (o._drawCalls.Count > 0)
                        {
                            DrawCall c = o._drawCalls[0];
                            if (c.MaterialNode != null && c.VisibilityBoneNode != null)
                            {
                                name += "_" + c.Material + "_" + c.VisibilityBone;
                            }
                        }
                    }
                    else
                    {
                        name += "ColorArray";
                    }

                    v.Name = g.FindName(name);
                }
            }
        }
Beispiel #3
0
        private void SendActiveEvent(MouseInput input)
        {
            InputData newInput = CreateInputData(input);

            switch (input.State)
            {
            case InputState.Start:
                StartDraw?.Invoke(newInput);
                _previousInput = newInput;
                break;

            case InputState.Draw:
                if (newInput.Position != _previousInput.Position)
                {
                    DrawCall?.Invoke(newInput);
                    _previousInput = newInput;
                }
                break;

            case InputState.End:
                EndDraw?.Invoke(newInput);
                _previousInput = default;
                break;

            default:
                throw new Exception("Try send active event to disactive input");
            }
        }
Beispiel #4
0
    void Start()
    {
        DrawCall drawCall = new DrawCall(new Sphere("球形"), new OpenGL());

        drawCall.StartDraw();
        drawCall.StopDraw();
    }
Beispiel #5
0
        /// <summary>
        /// Get the vertex shader output for the
        /// respective primitive ID and instance.
        /// </summary>
        /// <param name="primitiveID"></param>
        /// <param name="instanceID"></param>
        private void GetVertexShaderOutput(int primitiveID, int instanceID)
        {
            if (DrawCall?.cmd?.Count == 0)
            {
                return;
            }
            var vertexShader = VertexShader;

            // set shader input
            gl_PrimitiveIDIn = primitiveID;

            // load patch data from vertex shader
            var patch = DrawCall.GetPatch(primitiveID);

            DebugGetError(new StackTrace(true));
            gl_in = __InOut.Create(patch.Length);
            for (int i = 0; i < patch.Length; i++)
            {
                // compute vertex shader output
                var vertexID = Convert.ToInt32(patch.GetValue(i));
                vertexShader.Execute(vertexID, instanceID);
                // set geometry shader built in input varyings
                gl_in[i].gl_Position  = vertexShader.GetOutputVarying <vec4>("gl_Position");
                gl_in[i].gl_PointSize = vertexShader.GetOutputVarying <float>("gl_PointSize");
                var clipDistance = vertexShader.GetOutputVarying <float[]>("gl_ClipDistance");
                for (int j = 0; j < clipDistance.Length; j++)
                {
                    gl_in[i].gl_ClipDistance[j] = clipDistance[j];
                }
                // set geometry shader user input varyings
                ProcessFields(this, ProcessInField, new[] { typeof(__in) }, i);
            }
        }
Beispiel #6
0
 /// <summary>
 /// Uses the spriteBatch to draw a given Drawcall onto the active rendertarget. Must be within spriteBatch.begin/end
 /// </summary>
 /// <param name="spriteBatch">Spritebatch to use</param>
 /// <param name="drawCall">The drawcall to draw</param>
 protected void ApplyDrawCallToScene(SpriteBatch spriteBatch, DrawCall drawCall)
 {
     if (drawCall.texture == null)
     {
         //Text
         spriteBatch.DrawString(drawCall.font, drawCall.text, drawCall.position, drawCall.color, drawCall.rotation, drawCall.origin, drawCall.scale, drawCall.spriteEffects, drawCall.depth);
     }
     else
     {
         if (drawCall.useVectorPos)
         {
             if (drawCall.useSourceRectangle)
             {
                 spriteBatch.Draw(drawCall.texture, drawCall.position, drawCall.SourceRectangle, drawCall.color, drawCall.rotation, drawCall.origin, drawCall.scale, drawCall.spriteEffects, 0f);
             }
             else
             {
                 spriteBatch.Draw(drawCall.texture, drawCall.position, null, drawCall.color, drawCall.rotation, drawCall.origin, drawCall.scale, drawCall.spriteEffects, 0f);
             }
         }
         else
         {
             if (drawCall.useSourceRectangle)
             {
                 spriteBatch.Draw(drawCall.texture, drawCall.Rectangle, drawCall.SourceRectangle, drawCall.color, drawCall.rotation, drawCall.origin, drawCall.spriteEffects, 0f);
             }
             else
             {
                 spriteBatch.Draw(drawCall.texture, drawCall.Rectangle, null, drawCall.color, drawCall.rotation, drawCall.origin, drawCall.spriteEffects, 0f);
             }
         }
     }
 }
Beispiel #7
0
        /// <summary>
        /// Get the output from the vertex shader.
        /// </summary>
        /// <param name="primitiveID"></param>
        /// <param name="instanceID"></param>
        private void GetVertexShaderOutput(int primitiveID, int instanceID)
        {
            if (DrawCall?.cmd?.Count == 0)
            {
                return;
            }

            // load patch data from vertex shader
            var patch = DrawCall.GetPatch(primitiveID);

            DebugGetError(new StackTrace(true));

            gl_PatchVerticesIn = patch.Length;
            gl_PrimitiveID     = primitiveID;

            for (int i = 0; i < gl_PatchVerticesIn; i++)
            {
                // compute vertex shader data
                VertShader.Execute(Convert.ToInt32(patch.GetValue(i)), instanceID);
                // set input data for the vertex
                gl_in[i].gl_Position  = VertShader.GetOutputVarying <vec4>("gl_Position");
                gl_in[i].gl_PointSize = VertShader.GetOutputVarying <float>("gl_PointSize");
                var clipDistance = VertShader.GetOutputVarying <float[]>("gl_ClipDistance");
                for (int j = 0; j < clipDistance.Length; j++)
                {
                    gl_in[i].gl_ClipDistance[j] = clipDistance[j];
                }
            }
        }
Beispiel #8
0
        public void Draw(DrawCall.Tag tag, Texture2D texture, Rectangle rectangle, Rectangle sourceRectangle, Color color, float depth)
        {
            DrawCall toAdd = new DrawCall(tag, texture, rectangle, sourceRectangle, 0f, Vector2.Zero, color, depth, SpriteEffects.None);

            if (toAdd.Rectangle.Intersects(Game1.camera.Rectangle))
            {
                drawCalls.Add(depth, toAdd);
            }
        }
Beispiel #9
0
        public void Draw(DrawCall.Tag tag, Texture2D texture, Rectangle rectangle, float rotation, Vector2 origin, Color color, float depth)
        {
            DrawCall toAdd = new DrawCall(tag, texture, rectangle, rotation, origin, color, depth, SpriteEffects.None);

            if (toAdd.Rectangle.Intersects(Game1.camera.Rectangle))
            {
                drawCalls.Add(depth, toAdd);
            }
        }
Beispiel #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="tag"></param>
        /// <param name="texture"></param>
        /// <param name="rectangle"></param>
        /// <param name="sourceRectangle"></param>
        /// <param name="rotation"></param>
        /// <param name="origin"></param>
        /// <param name="color"></param>
        /// <param name="depth"></param>
        /// <param name="spriteEffects"></param>
        /// <param name="affectedByLight">0 - always dark, 1 - dynamic, 2 - always bright</param>
        /// <param name="lightBleedThrough">The amount of light able to pass through the object</param>
        public void Draw(DrawCall.Tag tag, Texture2D texture, Rectangle rectangle, Rectangle sourceRectangle, float rotation, Vector2 origin, Color color, float depth, SpriteEffects spriteEffects, short affectedByLight, float lightBleedThrough)
        {
            DrawCall toAdd = new DrawCall(tag, texture, rectangle, sourceRectangle, rotation, origin, color, depth, spriteEffects, affectedByLight, lightBleedThrough);

            if (toAdd.Rectangle.Intersects(Game1.camera.Rectangle))
            {
                drawCalls.Add(depth, toAdd);
            }
        }
Beispiel #11
0
        public void Draw(DrawCall.Tag tag, Texture2D texture, Vector2 position, Rectangle sourceRectangle, Vector2 scale, float rotation, Vector2 origin, Color color, float depth, SpriteEffects spriteEffects)
        {
            DrawCall toAdd = new DrawCall(tag, texture, position, sourceRectangle, scale, rotation, origin, color, depth, spriteEffects, 0, 0);

            if (toAdd.Rectangle.Intersects(Game1.camera.Rectangle))
            {
                drawCalls.Add(depth, toAdd);
            }
        }
Beispiel #12
0
        private static void WritePolygon(StreamWriter writer, DrawCall c)
        {
            MDL0ObjectNode poly = c._parentObject;

            if (poly._manager._vertices != null)
            {
                int       count    = poly._manager._vertices.Count;
                Vector3[] Vertices = new Vector3[count];

                //Weight vertices
                poly.Model.WeightMeshes();

                //Set weighted positions
                for (int i = 0; i < count; i++)
                {
                    Vertices[i] = poly._manager._vertices[i].WeightedPosition;
                }

                WriteVertexGroup(writer, Vertices);
            }

            if (poly._manager._faceData[1] != null)
            {
                WriteNormalGroup(writer, poly._manager, true);
            }

            for (int i = 0; i < 1; i++) //Obj only supports 1 uv coord set...
            {
                if (poly._manager._faceData[i + 4] != null)
                {
                    WriteUVGroup(writer, poly._manager._faceData[i + 4]);
                }
            }

            writer.WriteLine();
            writer.WriteLine(string.Format("g {0}", poly.Name));
            if (c._material != null)
            {
                WriteMaterial(writer, c._material);
            }

            if (poly._manager != null)
            {
                if (poly._manager._triangles != null)
                {
                    WriteTriList(writer, poly._manager);
                }
                //if (poly._manager._lines != null)
                //{

                //}
                //if (poly._manager._points != null)
                //{

                //}
            }
        }
 private void btnNew_Click(object sender, EventArgs e)
 {
     if (_targetObject != null)
     {
         DrawCall d = new DrawCall(_targetObject);
         _targetObject._drawCalls.Add(d);
         _targetObject.OnDrawCallsChanged();
         _targetObject.Model.RegenerateVIS0Indices();
         _targetObject.SignalPropertyChange();
     }
 }
Beispiel #14
0
//#endif

        private static void RegisterDrawCall(DrawType type, Color color, params object[] parameters)
        {
#if UNITY_EDITOR
            Initialize();
            DrawCall call = new DrawCall()
            {
                type = type, color = color, parameters = parameters
            };
            drawCalls.Enqueue(call);
            //drawCalls.Add(call);
#else
            Debug.LogWarning("Trying to register a debug draw on a non editor build!");
#endif
        }
        private void numDrawOrder_ValueChanged(object sender, EventArgs e)
        {
            if (_updating)
            {
                return;
            }

            DrawCall drawCall = lstDrawCalls.SelectedItem as DrawCall;

            if (drawCall != null)
            {
                drawCall.DrawPriority = (byte)numDrawOrder.Value;
            }
        }
        private void cboDrawPass_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_updating)
            {
                return;
            }

            DrawCall drawCall = lstDrawCalls.SelectedItem as DrawCall;

            if (drawCall != null)
            {
                drawCall.DrawPass = (DrawCall.DrawPassType)cboDrawPass.SelectedIndex;
            }
        }
Beispiel #17
0
        /// <summary>
        /// Uses the spriteBatch to draw a given Drawcall onto the active rendertarget. Must be within spriteBatch.begin/end
        /// Draws the depth of the object as the amount of red color and the rest 0
        /// </summary>
        /// <param name="spriteBatch">Spritebatch to use</param>
        /// <param name="drawCall">The drawcall to draw</param>
        protected void ApplyDrawCallDepthToMask(SpriteBatch spriteBatch, DrawCall drawCall)
        {
            float depth             = drawCall.depth;
            float lightBleedThrough = drawCall.lightBleedThrough;

            if (drawCall.affectedByLight == 0)
            {
                depth             = 1;
                lightBleedThrough = 1;
            }
            else if (drawCall.affectedByLight == 2)
            {
                depth             = 0;
                lightBleedThrough = 0;
            }



            if (drawCall.texture == null)
            {
                //Text
                spriteBatch.DrawString(drawCall.font, drawCall.text, drawCall.position, drawCall.color, drawCall.rotation, drawCall.origin, drawCall.scale, drawCall.spriteEffects, drawCall.depth);
            }
            else
            {
                if (drawCall.useVectorPos)
                {
                    if (drawCall.useSourceRectangle)
                    {
                        spriteBatch.Draw(drawCall.texture, drawCall.position, drawCall.SourceRectangle, new Color(depth, 1 - lightBleedThrough, 0, 1), drawCall.rotation, drawCall.origin, drawCall.scale, drawCall.spriteEffects, 0f);
                    }
                    else
                    {
                        spriteBatch.Draw(drawCall.texture, drawCall.position, null, new Color(depth, 1 - lightBleedThrough, 0, 1), drawCall.rotation, drawCall.origin, drawCall.scale, drawCall.spriteEffects, 0f);
                    }
                }
                else
                {
                    if (drawCall.useSourceRectangle)
                    {
                        spriteBatch.Draw(drawCall.texture, drawCall.Rectangle, drawCall.SourceRectangle, new Color(depth, 1 - lightBleedThrough, 0, 1), drawCall.rotation, drawCall.origin, drawCall.spriteEffects, 0f);
                    }
                    else
                    {
                        spriteBatch.Draw(drawCall.texture, drawCall.Rectangle, null, new Color(depth, 1 - lightBleedThrough, 0, 1), drawCall.rotation, drawCall.origin, drawCall.spriteEffects, 0f);
                    }
                }
            }
        }
        private void cboVisBone_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_updating)
            {
                return;
            }

            DrawCall drawCall = lstDrawCalls.SelectedItem as DrawCall;

            if (drawCall != null)
            {
                drawCall.VisibilityBoneNode = cboVisBone.SelectedItem as MDL0BoneNode;
                drawCall._parentObject.Model.RegenerateVIS0Indices();
                drawCall._parentObject.SignalPropertyChange();
            }
        }
Beispiel #19
0
        //Called every frame, after update has completed. It is wrapped in code that
        //managed the render state, so don't call DrawCall.Perform() outside of here.
        static void Render()
        {
            //First we setup our draw call
            var draw = new DrawCall(null, material, mesh, BlendMode.Premultiplied);

            material.SetMatrix4x4("Matrix", Matrix4x4.CreateOrthographic(Screen.Width, Screen.Height, -1f, 1f));

            //Then we'll draw the logo
            {
                //The material is how we interact with shaders
                material.SetTexture("Texture", logo);

                //A mesh defines the geometry of what we're drawing
                mesh.Clear();
                var rect = Rectangle.Box(new Vector2(Screen.Width / 2, Screen.Height / 2 - 32), logo.Width, logo.Height);
                mesh.AddRect(rect, Vector2.Zero, Vector2.One);
                mesh.Update();

                //To render, we setup a draw call and then perform it

                draw.Perform(PrimitiveType.Triangles);
            }

            //After we call Perform(), we can change stuff and then call Perform() again
            //The the rendering system will internally optimize the draw state
            {
                material.SetTexture("Texture", star);

                mesh.Clear();
                for (int i = 0; i < positions.Length; ++i)
                {
                    float a = i / (positions.Length - 1f);
                    mesh.AddRect(positions[i], Vector2.Zero, Vector2.One);
                }
                mesh.Update();

                draw.Perform(PrimitiveType.Triangles);
            }


            //This might seem tedious, but in reality this will be wrapped in components
            //or some kind of rendering class! For example, the Atlas automatically allows
            //us to pack textures/fonts into atlases, and the DrawBatch2D allows us to
            //use simple draw functions between a Begin() and End()
            //We just want to provide a low-level API so you have lots of options
        }
 public IDrawCall[] Process(IScene scene)
 {
     IDrawCall[] drawCalls = new DrawCall[scene.meshes.Length];
     for (int i = drawCalls.Length - 1; i >= 0; i--)
     {
         IMesh     mesh     = scene.meshes[i];
         IDrawCall drawCall = new DrawCall();
         drawCall.vertices = Array.ConvertAll <Vector3, Vector4>(mesh.vertices, (Vector3 each) => new Vector4(each.x, each.y, each.z, 1));
         drawCall.normals  = new Vector3[mesh.normals.Length];
         mesh.normals.CopyTo(drawCall.normals, 0);
         drawCall.indices = new int[mesh.indices.Length];
         mesh.indices.CopyTo(drawCall.indices, 0);
         drawCall.M   = mesh.M;
         drawCalls[i] = drawCall;
     }
     return(drawCalls);
 }
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (lstDrawCalls.SelectedIndices != null)
            {
                for (int x = lstDrawCalls.SelectedIndices.Count - 1; x >= 0; x--)
                {
                    DrawCall drawCall = lstDrawCalls.Items[lstDrawCalls.SelectedIndices[x]] as DrawCall;
                    if (drawCall != null)
                    {
                        MDL0ObjectNode o = drawCall._parentObject;

                        o._drawCalls.Remove(drawCall);
                        o.OnDrawCallsChanged();
                        o.Model.RegenerateVIS0Indices();
                        o.SignalPropertyChange();
                    }
                }
            }
        }
        private void lstDrawCalls_DoubleClick(object sender, EventArgs e)
        {
            if (_updating)
            {
                return;
            }

            DrawCall drawCall = lstDrawCalls.SelectedItem as DrawCall;

            if (drawCall != null)
            {
                drawCall._render = !drawCall._render;
                lstDrawCalls.SetItemChecked(lstDrawCalls.SelectedIndex, drawCall._render);

                if (_targetObject?.Model != null)
                {
                    TKContext.InvalidateModelPanels(_targetObject.Model);
                }
            }
        }
Beispiel #23
0
        public void Draw(object sender, GraphicsEventArgs args)
        {
            for (int i = 0; i < this.calls.Count; i++)
            {
                DrawCall call = calls[i];

                if (Environment.TickCount <= call.ValidUntil)
                {
                    Vector2 position       = this.Scale(call.RenderX, call.RenderY);
                    Vector2 size           = this.Scale(call.Width, call.Height);
                    Vector2 rotationCenter = new Vector2(position.X + (size.X * call.RotationCenterX), position.Y + (size.Y * call.RotationCenterY));
                    args.Graphics.DrawTexture(this.textures[call.TextureId], position, size, 0.0f, 0.0f, 1.0f, 1.0f, call.Rotation, rotationCenter);
                }
                else
                {
                    calls.Remove(call);
                    i--;
                }
            }
        }
        private void cboMaterial_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (_updating)
            {
                return;
            }

            DrawCall drawCall = lstDrawCalls.SelectedItem as DrawCall;

            if (drawCall != null)
            {
                drawCall.MaterialNode = cboMaterial.SelectedItem as MDL0MaterialNode;
                drawCall._parentObject.SignalPropertyChange();

                //lstDrawCalls.BeginUpdate();
                //int i = lstDrawCalls.SelectedIndex;
                //lstDrawCalls.DataSource = _targetObject._drawCalls;
                //lstDrawCalls.SelectedIndex = i;
                //lstDrawCalls.EndUpdate();
            }
        }
        private void lstDrawCalls_SelectedIndexChanged(object sender, EventArgs e)
        {
            DrawCall drawCall = lstDrawCalls.SelectedItem as DrawCall;

            if (drawCall != null)
            {
                _updating = true;

                cboMaterial.SelectedIndex = drawCall.MaterialNode != null ? drawCall.MaterialNode.Index : -1;
                cboVisBone.SelectedIndex  = drawCall.VisibilityBoneNode != null ? drawCall.VisibilityBoneNode.BoneIndex : -1;

                _prevDrawOrder            = numDrawOrder.Value = drawCall.DrawPriority;
                numDrawOrder.Enabled      = !(chkDoesntMatter.Checked = drawCall.DrawPriority == 0);
                cboDrawPass.SelectedIndex = (int)drawCall.DrawPass;
                lstDrawCalls.SetItemChecked(lstDrawCalls.SelectedIndex, drawCall._render);

                _updating = false;

                //drawCall._render = true;
            }
        }
Beispiel #26
0
 public IGraphicsService PushDrawCall(string DrawStackID, DrawCall DC)
 {
     _drawStacks[DrawStackID].PushDrawCall(DC);
     return(this);
 }
Beispiel #27
0
 public void SetLastUser(DrawCall lastUser) => LastUser = lastUser;
        private Mesh CreateGltfMesh(string meshName, VMesh vmesh, ModelRoot model, bool includeJoints)
        {
            ProgressDialog.SetProgress($"Creating mesh: {meshName}");

            var data = vmesh.GetData();
            var vbib = vmesh.VBIB;

            var mesh = model.CreateMesh(meshName);

            mesh.Name = meshName;

            foreach (var sceneObject in data.GetArray("m_sceneObjects"))
            {
                foreach (var drawCall in sceneObject.GetArray("m_drawCalls"))
                {
                    var vertexBufferInfo  = drawCall.GetArray("m_vertexBuffers")[0]; // In what situation can we have more than 1 vertex buffer per draw call?
                    var vertexBufferIndex = (int)vertexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var vertexBuffer      = vbib.VertexBuffers[vertexBufferIndex];

                    var indexBufferInfo  = drawCall.GetSubCollection("m_indexBuffer");
                    var indexBufferIndex = (int)indexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var indexBuffer      = vbib.IndexBuffers[indexBufferIndex];

                    // Create one primitive per draw call
                    var primitive = mesh.CreatePrimitive();

                    // Avoid duplicate attribute names
                    var attributeCounters = new Dictionary <string, int>();

                    // Set vertex attributes
                    foreach (var attribute in vertexBuffer.Attributes)
                    {
                        attributeCounters.TryGetValue(attribute.Name, out var attributeCounter);
                        attributeCounters[attribute.Name] = attributeCounter + 1;
                        var accessorName = GetAccessorName(attribute.Name, attributeCounter);

                        var buffer        = ReadAttributeBuffer(vertexBuffer, attribute);
                        var numComponents = buffer.Length / vertexBuffer.Count;

                        if (attribute.Name == "BLENDINDICES")
                        {
                            if (!includeJoints)
                            {
                                continue;
                            }

                            var byteBuffer    = buffer.Select(f => (byte)f).ToArray();
                            var rawBufferData = new byte[buffer.Length];
                            System.Buffer.BlockCopy(byteBuffer, 0, rawBufferData, 0, rawBufferData.Length);

                            var bufferView = mesh.LogicalParent.UseBufferView(rawBufferData);
                            var accessor   = mesh.LogicalParent.CreateAccessor();
                            accessor.SetVertexData(bufferView, 0, buffer.Length / 4, DimensionType.VEC4, EncodingType.UNSIGNED_BYTE);

                            primitive.SetVertexAccessor(accessorName, accessor);

                            continue;
                        }

                        if (attribute.Name == "NORMAL" && DrawCall.IsCompressedNormalTangent(drawCall))
                        {
                            var vectors = ToVector4Array(buffer);
                            var(normals, tangents) = DecompressNormalTangents(vectors);
                            primitive.WithVertexAccessor("NORMAL", normals);
                            primitive.WithVertexAccessor("TANGENT", tangents);

                            continue;
                        }

                        if (attribute.Name == "BLENDINDICES")
                        {
                            var byteBuffer = buffer.Select(f => (byte)f).ToArray();
                            var bufferView = mesh.LogicalParent.UseBufferView(byteBuffer);
                            var accessor   = mesh.LogicalParent.CreateAccessor();
                            accessor.SetVertexData(bufferView, 0, buffer.Length / 4, DimensionType.VEC4, EncodingType.UNSIGNED_BYTE);

                            primitive.SetVertexAccessor(accessorName, accessor);

                            continue;
                        }

                        if (attribute.Name == "TEXCOORD" && numComponents != 2)
                        {
                            // We are ignoring some data, but non-2-component UVs cause failures in gltf consumers
                            continue;
                        }

                        switch (numComponents)
                        {
                        case 4:
                        {
                            var vectors = ToVector4Array(buffer);
                            primitive.WithVertexAccessor(accessorName, vectors);
                            break;
                        }

                        case 3:
                        {
                            var vectors = ToVector3Array(buffer);
                            primitive.WithVertexAccessor(accessorName, vectors);
                            break;
                        }

                        case 2:
                        {
                            var vectors = ToVector2Array(buffer);
                            primitive.WithVertexAccessor(accessorName, vectors);
                            break;
                        }

                        case 1:
                        {
                            primitive.WithVertexAccessor(accessorName, buffer);
                            break;
                        }

                        default:
                            throw new NotImplementedException($"Attribute \"{attribute.Name}\" has {numComponents} components");
                        }
                    }

                    // For some reason soruce models can have joints but no weights, check if that is the case
                    var jointAccessor = primitive.GetVertexAccessor("JOINTS_0");
                    if (jointAccessor != null && primitive.GetVertexAccessor("WEIGHTS_0") == null)
                    {
                        // If this occurs, give default weights
                        var defaultWeights = Enumerable.Repeat(Vector4.UnitX, jointAccessor.Count).ToList();
                        primitive.WithVertexAccessor("WEIGHTS_0", defaultWeights);
                    }

                    // Set index buffer
                    var startIndex = (int)drawCall.GetIntegerProperty("m_nStartIndex");
                    var indexCount = (int)drawCall.GetIntegerProperty("m_nIndexCount");
                    var indices    = ReadIndices(indexBuffer, startIndex, indexCount);
                    primitive.WithIndicesAccessor(PrimitiveType.TRIANGLES, indices);

                    // Add material
                    var materialPath = drawCall.GetProperty <string>("m_material");

                    ProgressDialog.SetProgress($"Loading material: {materialPath}");

                    var materialResource = GuiContext.LoadFileByAnyMeansNecessary(materialPath + "_c");

                    if (materialResource == null)
                    {
                        continue;
                    }

                    var renderMaterial = (VMaterial)materialResource.DataBlock;

                    var materialNameTrimmed = Path.GetFileNameWithoutExtension(materialPath);
                    var bestMaterial        = GenerateGLTFMaterialFromRenderMaterial(renderMaterial, model, materialNameTrimmed);
                    primitive.WithMaterial(bestMaterial);
                }
            }

            return(mesh);
        }
Beispiel #29
0
        private Mesh CreateGltfMesh(string meshName, VMesh vmesh, ModelRoot model)
        {
            ProgressDialog.SetProgress($"Creating mesh: {meshName}");

            var data = vmesh.GetData();
            var vbib = vmesh.VBIB;

            var mesh = model.CreateMesh(meshName);

            mesh.Name = meshName;

            foreach (var sceneObject in data.GetArray("m_sceneObjects"))
            {
                foreach (var drawCall in sceneObject.GetArray("m_drawCalls"))
                {
                    var vertexBufferInfo  = drawCall.GetArray("m_vertexBuffers")[0]; // In what situation can we have more than 1 vertex buffer per draw call?
                    var vertexBufferIndex = (int)vertexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var vertexBuffer      = vbib.VertexBuffers[vertexBufferIndex];

                    var indexBufferInfo  = drawCall.GetSubCollection("m_indexBuffer");
                    var indexBufferIndex = (int)indexBufferInfo.GetIntegerProperty("m_hBuffer");
                    var indexBuffer      = vbib.IndexBuffers[indexBufferIndex];

                    // Create one primitive per draw call
                    var primitive = mesh.CreatePrimitive();

                    // Avoid duplicate attribute names
                    var uniqueAttributes = vertexBuffer.Attributes.GroupBy(a => a.Name).Select(g => g.First());

                    // Set vertex attributes
                    foreach (var attribute in uniqueAttributes)
                    {
                        if (AccessorInfo.TryGetValue(attribute.Name, out var accessorInfo))
                        {
                            var buffer = ReadAttributeBuffer(vbib, vertexBuffer, attribute);

                            if (accessorInfo.NumComponents == 4)
                            {
                                var vectors = ToVector4Array(buffer);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                            else if (attribute.Name == "NORMAL" && DrawCall.IsCompressedNormalTangent(drawCall))
                            {
                                var vectors = ToVector4Array(buffer);
                                var(normals, tangents) = DecompressNormalTangents(vectors);
                                primitive.WithVertexAccessor("NORMAL", normals);
                                primitive.WithVertexAccessor("TANGENT", tangents);
                            }
                            else if (accessorInfo.NumComponents == 3)
                            {
                                var vectors = ToVector3Array(buffer, true, accessorInfo.Resize);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                            else if (accessorInfo.NumComponents == 2)
                            {
                                var vectors = ToVector2Array(buffer);
                                primitive.WithVertexAccessor(accessorInfo.GltfAccessorName, vectors);
                            }
                        }
                    }

                    // Set index buffer
                    var indices = ReadIndices(indexBuffer);

                    // For triangle primitives, the front face has to be in counter-clockwise (CCW) winding order.
                    for (var i = 0; i < indices.Length; i += 3)
                    {
                        var b = indices[i + 2];
                        indices[i + 2] = indices[i + 1];
                        indices[i + 1] = b;
                    }

                    primitive.WithIndicesAccessor(PrimitiveType.TRIANGLES, indices);

                    // Add material
                    var materialPath = drawCall.GetProperty <string>("m_material");

                    ProgressDialog.SetProgress($"Loading material: {materialPath}");

                    var materialResource = GuiContext.LoadFileByAnyMeansNecessary(materialPath + "_c");

                    if (materialResource == null)
                    {
                        continue;
                    }

                    var renderMaterial = (VMaterial)materialResource.DataBlock;

                    var materialNameTrimmed = Path.GetFileNameWithoutExtension(materialPath);
                    var bestMaterial        = GenerateGLTFMaterialFromRenderMaterial(renderMaterial, model, materialNameTrimmed);
                    primitive.WithMaterial(bestMaterial);
                }
            }

            return(mesh);
        }
Beispiel #30
0
        public void UpdateVis0(int objectIndex, int drawCallIndex, bool value)
        {
            BRESEntryNode n;

            if ((n = TargetAnimation as BRESEntryNode) == null ||
                _animFrame == 0 ||
                TargetModel == null)
            {
                return;
            }

Start:
            if (_vis0 != null)
            {
                if (objectIndex < 0 || objectIndex >= TargetModel.Objects.Length)
                {
                    return;
                }

                MDL0ObjectNode obj = (MDL0ObjectNode)TargetModel.Objects[objectIndex];

                if (drawCallIndex < 0 || drawCallIndex >= obj._drawCalls.Count)
                {
                    return;
                }

                DrawCall     c    = obj._drawCalls[drawCallIndex];
                MDL0BoneNode bone = c._visBoneNode;

                if (bone == null)
                {
                    return;
                }

                VIS0EntryNode node = null;
                if ((node = (VIS0EntryNode)_vis0.FindChild(bone.Name, true)) == null && bone.BoneIndex != 0 && bone.Name != "EyeYellowM")
                {
                    node      = _vis0.CreateEntry();
                    node.Name = bone.Name;
                    node.MakeConstant(true);
                }

                bool ANIMval = value;

                bool nowAnimated = false, alreadyConstant = false;
Top:
                if (node != null)
                {
                    if (node._entryCount != 0) //Node is animated
                    {
                        bool VIS0val = node.GetEntry((int)_animFrame - 1);

                        if (VIS0val != ANIMval)
                        {
                            node.SetEntry((int)_animFrame - 1, ANIMval);
                        }
                    }
                    else //Node is constant
                    {
                        alreadyConstant = true;

                        bool VIS0val = node._flags.HasFlag(VIS0Flags.Enabled);

                        if (VIS0val != ANIMval)
                        {
                            node.MakeAnimated();
                            nowAnimated = true;
                            goto Top;
                        }
                    }
                }

                //Check if the entry can be made constant.
                //No point if the entry has just been made animated or if the node is already constant.
                if (node != null && !alreadyConstant && !nowAnimated)
                {
                    bool constant = true;
                    for (int i = 0; i < node._entryCount; i++)
                    {
                        if (i == 0)
                        {
                            continue;
                        }

                        if (node.GetEntry(i - 1) != node.GetEntry(i))
                        {
                            constant = false;
                            break;
                        }
                    }
                    if (constant)
                    {
                        node.MakeConstant(node.GetEntry(0));
                    }
                }

                var t = (VIS0EntryNode)KeyframePanel.visEditor.TargetNode;
                if (node != null && t != null && t.Name == node.Name)
                {
                    VIS0Editor.UpdateEntry();
                }
            }
            else
            {
                CreateVIS0();
                if (_vis0 != null)
                {
                    goto Start;
                }
            }
        }