예제 #1
0
                public Channel(Document doc, Model model, Document.Channel channel, Dictionary<string, Sampler> samplers)
                {
                    if (!samplers.TryGetValue(channel.source.id, out sampler))
                        throw new ColladaException("can't find source with id " + channel.source.id + " of <channel>");

                    Bone bone;
                    string targetNodeId = COLLADAUtil.GetTargetNodeId(doc, channel.target);
                    if (!model.BonesTable.TryGetValue(targetNodeId, out bone))
                        throw new ColladaException("can't find target node in <channel>");

                    string[] tmp = channel.target.Split('/');
                    tmp = tmp[tmp.Length - 1].Split('.');
                    string targetTransformId = tmp[0];
                    if (tmp.Length == 1)
                        targetTransformKey = null;
                    else
                        targetTransformKey = tmp[1];

                    if (!bone.Transforms.TryGetValue(targetTransformId, out transform))
                        throw new ColladaException("can't find target transformation '" + targetTransformId + "' in <channel>");

                    transform.AddChannel(this);
                }
예제 #2
0
        /// <summary>
        /// Create a BasicMaterial from a "<material>".
        /// <param name="material">The "<material>" element to be converted.</param>
        /// <param name="context"> The current context for the COLLADA Processor</param>
        /// </summary>
        public BasicMaterial CreateBasicMaterial(Model model, Document.Material material)
        {
            Document doc = model.Doc;
            uint textureChannel = 0;

            Dictionary<string, uint> textureBinding = new Dictionary<string, uint>();
            textureBindings[material.id] = textureBinding;
            BasicMaterial materialContent = new BasicMaterial();
            Document.Effect effect = (Document.Effect)doc.dic[material.instanceEffect.Fragment];

            if (effect == null) throw new Exception("cannot find effect#" + material.instanceEffect.Fragment);
            // search common profile with correct asset....
            Document.ProfileCOMMON profile;
            foreach (Document.IProfile tmpProfile in effect.profiles)
            {
                if (tmpProfile is Document.ProfileCOMMON)
                {
                    profile = (Document.ProfileCOMMON)tmpProfile;
                    goto Found;
                }
            }
            throw new Exception("Could not find profile_COMMON in effect" + effect.ToString());
            Found:
            // read params
            // Dictionary<string, string> samplerBind = new Dictionary<string, string>();
            // Dictionary<string, string> imageBind = new Dictionary<string, string>();

            // Read Technique
            Document.SimpleShader shader = ((Document.ProfileCOMMON)profile).technique.shader;

            materialContent.Name = material.name;
            // BasicShader only accept texture for the diffuse channel
            if (shader.diffuse is Document.Texture)
            {
                string sampler = ((Document.Texture)shader.diffuse).texture;
                string surface;
                string image;
                if (profile.newParams.ContainsKey(sampler))
                {
                    surface = ((Document.Sampler2D)profile.newParams[sampler].param).source;
                    image = ((Document.Surface)profile.newParams[surface].param).initFrom;
                }
                else
                {
                    image = sampler;
                    // TODO: emit serious warning - invalid content
                }
                // now find image
                string imagePath = ((Document.Image)doc.dic[image]).init_from.Uri.LocalPath;
                // here associate 1 texture binding per texture in material
                textureBinding[((Document.Texture)shader.diffuse).texcoord] = textureChannel++;
                materialContent.Texture = imagePath;
            }
            else if (shader.diffuse is Document.Color)
            {
                Document.Color color = (Document.Color)shader.diffuse;
                // TODO: manage color[3] in transparency
                materialContent.DiffuseColor = new Vector3(color[0], color[1], color[2]);
            }
            if (shader.ambient is Document.Texture)
            {
                // Basic Material does not accept texture on ambient channel
                COLLADAUtil.Log("Ambient channel not supported in BasicMaterial.");
                /*
                string sampler = ((Document.Texture)shader.ambient).texture;
                string surface = ((Document.Sampler2D)profile.newParams[sampler].param).source;
                string image = ((Document.Surface)profile.newParams[surface].param).initFrom;
                // now find image
                string imagePath = ((Document.Image)doc.dic[image]).init_from.Uri.LocalPath;
                // here associate 1 texture binding per texture in material
                textureBinding[((Document.Texture)shader.ambient).texcoord] = textureChannel++;
                materialContent.Texture = new ExternalReference<TextureContent>(imagePath);
                 */

            }
            else if (shader.ambient is Document.Color)
            {
                // XNA BasicMaterial has no ambient
                COLLADAUtil.Log("Ambient channel not supported in BasicMaterial.");
            }
            if (shader.emission is Document.Texture)
            {
                // XNA BasicMaterial does not accept texture for emmision
                COLLADAUtil.Log("BasicMaterial does not accept texture for emmision.");
                /*
                string sampler = ((Document.Texture)shader.emission).texture;
                string surface = ((Document.Sampler2D)profile.newParams[sampler].param).source;
                string image = ((Document.Surface)profile.newParams[surface].param).initFrom;
                // now find image
                string imagePath = ((Document.Image)doc.dic[image]).init_from.Uri.LocalPath;
                // here associate 1 texture binding per texture in material
                textureBinding[((Document.Texture)shader.emission).texcoord] = textureChannel++;
                materialContent.Texture = new ExternalReference<TextureContent>(imagePath);
                 */
            }
            else if (shader.emission is Document.Color)
            {
                Document.Color color = (Document.Color)shader.emission;
                materialContent.EmissiveColor = new Vector3(color[0], color[1], color[2]);
            }
            if (shader.specular is Document.Texture)
            {
                // XNA BasicMaterial does not accept texture for specular
                COLLADAUtil.Log("BasicMaterial does not accept texture for specular.");
                /*
                string sampler = ((Document.Texture)shader.specular).texture;
                string surface = ((Document.Sampler2D)profile.newParams[sampler].param).source;
                string image = ((Document.Surface)profile.newParams[surface].param).initFrom;
                // now find image
                string imagePath = ((Document.Image)doc.dic[image]).init_from.Uri.LocalPath;
                // here associate 1 texture binding per texture in material
                textureBinding[((Document.Texture)shader.specular).texcoord] = textureChannel++;
                materialContent.Texture = new ExternalReference<TextureContent>(imagePath);
                 */
            }
            else if (shader.specular is Document.Color)
            {
                Document.Color color = (Document.Color)shader.specular;
                materialContent.SpecularColor = new Vector3(color[0], color[1], color[2]);
                if (shader.shininess is Document.Float)
                    materialContent.SpecularPower = ((Document.Float)shader.shininess).theFloat;
            }
            if (shader.transparency is Document.Texture)
            {
                // XNA Basic Shader does not accept a texture for the transparency channel
                COLLADAUtil.Log("BasicMaterial does not accept texture for transparency channel.");
                /*
                string sampler = ((Document.Texture)shader.transparency).texture;
                string surface = ((Document.Sampler2D)profile.newParams[sampler].param).source;
                string image = ((Document.Surface)profile.newParams[surface].param).initFrom;
                // now find image
                string imagePath = ((Document.Image)doc.dic[image]).init_from.Uri.LocalPath;
                // here associate 1 texture binding per texture in material
                textureBinding[((Document.Texture)shader.transparency).texcoord] = textureChannel++;
                materialContent.Texture = new ExternalReference<TextureContent>(imagePath);
                 */
            }
            else if (shader.transparency is Document.Float)
            {
                materialContent.Alpha = ((Document.Float)shader.transparency).theFloat;
            }

            return materialContent;
        }
예제 #3
0
            public Animation(Document doc, Model model, Document.Animation animation)
            {
                children = new List<Animation>();
                samplers = new Dictionary<string, Sampler>();
                channels = new List<Channel>();

                if (animation.children != null)
                    foreach (Document.Animation childAnim in animation.children)
                        children.Add(new Animation(doc, model, childAnim));

                if (animation.channels != null && animation.samplers != null)
                {
                    foreach (Document.Sampler sampler in animation.samplers)
                        samplers.Add(sampler.id, new Sampler(doc, sampler));
                    foreach (Document.Channel channel in animation.channels)
                    {
                        try
                        {
                            channels.Add(new Channel(doc, model, channel, samplers));
                        }
                        catch (ColladaException e)
                        {
                            COLLADAUtil.Log(e);
                        }
                    }
                }
            }
예제 #4
0
 // Summary:
 //     Create a new Instance of a Mesh
 // Parameters:
 //   mesh:
 //     the ModelMesh to instance
 //   parentBone:
 //     the bone that will give this instance its position
 //   materialBinding
 //     the binding between the material name and the name in the mesh parts
 //
 // Returns:
 //     A new instance of mesh
 public InstanceMesh(Model.CMesh mesh, Model.Bone parentBone, Dictionary<string, string> materialBinding)
 {
     this.mesh = mesh;
     this.parentBone = parentBone;
     this.materialBinding = materialBinding;
 }
예제 #5
0
            public CSkinnedMesh(Model model, Document.Geometry geo, Document.Skin skin)
                : base(model, geo)
            {
                this.geo = geo;
                this.model = model;
                this.skin = skin;

                /*
                foreach (Document.Input input in skin.joint.inputs)
                {
                    if (input.semantic == "JOINT")
                    {
                        Document.Source source = (Document.Source) input.source;
                        boneCount = ((Document.Array<string>) source.array).Count;
                    }
                }
                 */
            }
예제 #6
0
            public CMesh(Model model, Document.Geometry geo)
            {
                this.geo = geo;
                Document doc = model.Doc;

                bool first = true;

                int vertexIndex = 0;
                List<int> indexBuffer = new List<int>();
                List<float> vertexBuffer = new List<float>();
                List<int> invVertexMappingList = new List<int>();
                Dictionary<string, int> mapping = new Dictionary<string, int>();
                List<float> tempValues = new List<float>();
                foreach (Document.Primitive primitive in geo.mesh.primitives)
                {
                    // Skip non-triangle primitives
                    if (!(primitive is Document.Triangle))
                    {
                        // Display a warning
                        COLLADAUtil.Log(COLLADALogType.Warning, "Skipping part of geometry '" + geo.id + "'! Make sure all primitives are triangles.");
                        continue;
                    }

                    #region vertex declaration
                    // Take the first primitive and use its inputs to build the
                    // vertex declaration and a dictionary to describe a mapping
                    // of n source/p_index pairs to one index in the vertex buffer.
                    // TODO: for now we assume that all primitives have the same
                    // inputs in equal order.
                    if (first)
                    {
                        first = false;

                        short deltaOffset = 0;
                        short offset = 0;
                        short streamOffset = 0;

                        DeclarationType vertexElementFormat;
                        DeclarationUsage vertexElementUsage;
                        byte usageIndex;
                        byte texcoordUsageIndex = 0;
                        foreach (Document.Input input in COLLADAUtil.GetAllInputs(primitive))
                        {
                            switch (input.semantic)
                            {
                                case "POSITION":
                                    vertexElementUsage = DeclarationUsage.Position;
                                    usageIndex = 0;
                                    break;
                                case "NORMAL":
                                    vertexElementUsage = DeclarationUsage.Normal;
                                    usageIndex = 0;
                                    break;
                                case "COLOR":
                                    vertexElementUsage = DeclarationUsage.Color;
                                    usageIndex = 0;
                                    break;
                                case "TEXCOORD":
                                    vertexElementUsage = DeclarationUsage.TextureCoordinate;
                                    usageIndex = texcoordUsageIndex++;
                                    break;
                                case "TEXTANGENT":
                                    vertexElementUsage = DeclarationUsage.Tangent;
                                    usageIndex = 0;
                                    break;
                                case "TEXBINORMAL":
                                    vertexElementUsage = DeclarationUsage.Binormal;
                                    usageIndex = 0;
                                    break;
                                default:
                                    throw new Exception("Unexeptected vertexElementUsage=" + input.semantic);
                            }

                            // assuming floats !o
                            switch (((Document.Source)input.source).accessor.ParameterCount)
                            {
                                case 2:
                                    vertexElementFormat = DeclarationType.Float2;
                                    deltaOffset = 2 * 4;
                                    vertexStride += 2;
                                    break;
                                case 3:
                                    vertexElementFormat = DeclarationType.Float3;
                                    deltaOffset = 3 * 4;
                                    vertexStride += 3;
                                    break;
                                case 4:
                                    vertexElementFormat = DeclarationType.Float4;
                                    deltaOffset = 4 * 4;
                                    vertexStride += 4;
                                    break;
                                default:
                                    throw new Exception("Unexpected vertexElementFormat");

                            }

                            vertexElements.Add(new VertexElement(streamOffset /* stream */,
                                                                 offset  /* offset */,
                                                                 vertexElementFormat,
                                                                 DeclarationMethod.Default,
                                                                 vertexElementUsage,
                                                                 usageIndex));

                            offset += deltaOffset;
                        }
                    }
                    #endregion

                    // Build vertex and index array
                    for (int v = 0; v < primitive.count * 3; v++)
                    {
                        int positionIndex = 0;
                        string indexKey = "";
                        tempValues.Clear();

                        foreach (Document.Input input in COLLADAUtil.GetAllInputs(primitive))
                        {
                            // Get index into source array of this input for this triangle t
                            int index = COLLADAUtil.GetPValue(input, primitive, v);

                            // Save index of position array for later inverse mapping
                            if (input.semantic == "POSITION")
                                positionIndex = index;

                            // Build key out of all indices for later lookup
                            indexKey += index + ",";
                            // Get values this index is referencing
                            float[] values = COLLADAUtil.GetSourceElement(doc, input, index);
                            // Add the values to temporary storage
                            tempValues.AddRange(values);
                        }

                        // Add this combination of inputs to the vertex buffer
                        if (mapping.ContainsKey(indexKey))
                            indexBuffer.Add(mapping[indexKey]);
                        else
                        {
                            mapping[indexKey] = vertexIndex;
                            indexBuffer.Add(vertexIndex);
                            vertexBuffer.AddRange(tempValues);
                            // Inverse mapping of vertex buffer index to index of original array
                            invVertexMappingList.Add(positionIndex);
                            // Increment index of vertex buffer
                            vertexIndex++;
                        }
                    }

                    primitives.Add(primitive);

                    faceCount += primitive.count;
                }

                vertexCount = vertexIndex;

                indexArray = indexBuffer.ToArray();
                vertexArray = vertexBuffer.ToArray();
                invVertexMapping = invVertexMappingList.ToArray();

                // Reverse triangle order for DirectX
                for (int i = 0; i < indexArray.Length; i += 3)
                {
                    int swap = indexArray[i];
                    indexArray[i] = indexArray[i + 2];
                    indexArray[i + 2] = swap;
                }

                foreach (VertexElement vertexElement in VertexElements)
                {
                    // Reverse texture 'T' coordinate for DirectX
                    if (vertexElement.Usage == DeclarationUsage.TextureCoordinate)
                    {
                        for (int i = 0; i < vertexCount; i++)
                        {
                            int offsetT = i * VertexStride + vertexElement.Offset / 4 + 1;
                            if (offsetT < vertexArray.Length)
                                vertexArray[offsetT] = 1.0f - vertexArray[offsetT];
                            else
                                throw new IndexOutOfRangeException();
                        }
                    }
                }

                FinalizeVertexDeclaration(vertexElements);
            }
예제 #7
0
 public Camera(Model model, Document.Camera cam)
 {
     if (cam.optics.perspectiveOrOrthographic is Document.Perspective)
     {
         Document.Perspective perspective = (Document.Perspective) cam.optics.perspectiveOrOrthographic;
         projectionMatrix = Matrix.PerspectiveFovLH(
             perspective.yfov.theFloat * DegToRad,
             perspective.aspect_ratio.theFloat,
             perspective.znear.theFloat,
             perspective.zfar.theFloat);
     }
     else
     {
         Document.Orthographic orthographic = (Document.Orthographic) cam.optics.perspectiveOrOrthographic;
         projectionMatrix = Matrix.OrthoLH(
             orthographic.xmag.theFloat,
             orthographic.ymag.theFloat,
             orthographic.znear.theFloat,
             orthographic.zfar.theFloat);
     }
 }
예제 #8
0
            public Bone(Model model, Bone _parent, string _name, string _nodeName, string _nodeType)
            {
                this.transforms = new Dictionary<string, Transform>();
                if (model.BonesTable.ContainsKey(_name))
                    _name = _parent.Name + "/" + _name;

                model.BonesTable.Add(_name, this);
                this.index = model.Bones.Count-1;
                this.children = new List<Bone>();
                name = _name;
                parent = _parent;
                nodeName = _nodeName;
                nodeType = _nodeType;
            }