예제 #1
1
        public void Export(string filePath)
        {
            PalletProperties palletProperties = _palletSolution.Analysis.PalletProperties;

            COLLADA model = new COLLADA();
            // asset
            model.asset = new asset()
            {
                created = DateTime.Now,
                modified = DateTime.Now
            };
            model.asset.keywords = "StackBuilder Pallet Case";
            model.asset.title = _palletSolution.Title;
            model.asset.unit = new assetUnit() { name = "millimeters", meter = 0.001 };
            model.asset.up_axis = UpAxisType.Z_UP;

            library_images images = new library_images();
            library_materials materials = new library_materials();
            library_effects effects = new library_effects();
            library_geometries geometries = new library_geometries();
            library_nodes nodes = new library_nodes();
            library_cameras cameras = new library_cameras();
            library_animations animations = new library_animations();
            library_visual_scenes scenes = new library_visual_scenes();

            COLLADAScene colladaScene = new COLLADAScene();

            model.Items = new Object[] { images, materials, effects, geometries, nodes, cameras, animations, scenes };
            model.scene = colladaScene;

            // colors and materials
            List<effect> listEffects = new List<effect>();
            List<material> listMaterials = new List<material>();
            List<image> listImages = new List<image>();

            // effects
            effect effectPallet;
            material materialPallet;
            CreateMaterial(palletProperties.Color, null, null, "Pallet", out effectPallet, out materialPallet);
            listEffects.Add(effectPallet);
            listMaterials.Add(materialPallet);

            Box box = new Box(0, _palletSolution.Analysis.BProperties);

            // build list of effects / materials / images
            uint faceIndex = 0;
            foreach (Face face in box.Faces)
            {
                // build texture image if any
                string textureName = null;
                if (face.HasBitmap)
                {
                    textureName = string.Format("textureFace_{0}", faceIndex);
                    string texturePath = System.IO.Path.Combine(
                        System.IO.Path.GetDirectoryName(filePath)
                        , textureName + ".jpg");

                    double dimX = 0.0, dimY = 0.0;

                    switch (faceIndex)
                    {
                        case 0: dimX = box.Width; dimY = box.Height; break;
                        case 1: dimX = box.Width; dimY = box.Height; break;
                        case 2: dimX = box.Length; dimY = box.Height; break;
                        case 3: dimX = box.Length; dimY = box.Height; break;
                        case 4: dimX = box.Length; dimY = box.Width; break;
                        case 5: dimX = box.Length; dimY = box.Width; break;
                        default: break;
                    }
                    face.ExtractFaceBitmap(dimX, dimY, _bmpWidth, texturePath);
                    // create image
                    listImages.Add(
                        new image()
                        {
                            id = textureName + ".jpg",
                            name = textureName + ".jpg",
                            Item = @".\" + textureName + @".jpg"
                        }
                    );
                }
                material materialCase;
                effect effectCase;
                CreateMaterial(face.ColorFill, textureName, "0", string.Format("Case{0}", faceIndex), out effectCase, out materialCase);
                listEffects.Add(effectCase);
                listMaterials.Add(materialCase);

                ++faceIndex;
            }

            // add to image list
            images.image = listImages.ToArray();

            // case lines material
            effect effectCaseLines;
            material materialCaseLines;
            CreateMaterial(Color.Black, null, null, "CaseLines", out effectCaseLines, out materialCaseLines);
            listEffects.Add(effectCaseLines);
            listMaterials.Add(materialCaseLines);
            effects.effect = listEffects.ToArray();
            materials.material = listMaterials.ToArray();

            // geometries
            geometry geomPallet = new geometry() { id = "palletGeometry", name = "palletGeometry" };
            geometry geomCase = new geometry() { id = "caseGeometry", name = "caseGeometry" };
            geometries.geometry = new geometry[] { geomPallet, geomCase };
            // pallet
            mesh meshPallet = CreatePalletMesh(palletProperties);
            geomPallet.Item = meshPallet;
            // case
            mesh meshCase = CreateCaseMesh(_palletSolution.Analysis.BProperties as BoxProperties);
            geomCase.Item = meshCase;
            // library_animations
            animation animationMain = new animation() { id = "animationMain_ID", name = "animationMain" };
            animations.animation = new animation[] { animationMain };

            List<object> listAnimationSource = new List<object>();

            // library_visual_scenes
            visual_scene mainScene = new visual_scene() { id = "MainScene", name = "MainScene" };
            scenes.visual_scene = new visual_scene[] { mainScene };

            List<node> sceneNodes = new List<node>();
            sceneNodes.Add(new node()
            {
                id = "PalletNode",
                name = "PalletNode",
                instance_geometry = new instance_geometry[]
                {
                    new instance_geometry()
                    {
                        url = "#palletGeometry",
                        bind_material = new bind_material()
                        {
                            technique_common = new instance_material[]
                            {
                                new instance_material()
                                {
                                    symbol="materialPallet",
                                    target=string.Format("#{0}", materialPallet.id)
                                }
                            }
                        }
                    }
                }
            });
            uint caseIndex = 0;
            foreach (ILayer layer in _palletSolution)
            {
                BoxLayer bLayer = layer as BoxLayer;
                if (null == bLayer) continue;

                foreach (BoxPosition bp in bLayer)
                {
                    Vector3D translation = bp.Position;
                    Vector3D rotations = bp.Transformation.Rotations;

                    node caseNode = new node()
                    {
                        id = string.Format("CaseNode_{0}_ID", caseIndex),
                        name = string.Format("CaseNode_{0}", caseIndex),
                        ItemsElementName = new ItemsChoiceType2[]
                        {
                            ItemsChoiceType2.translate,
                            ItemsChoiceType2.rotate,
                            ItemsChoiceType2.rotate,
                            ItemsChoiceType2.rotate
                        },
                        Items = new object[]
                        {
                            new TargetableFloat3()
                            {
                                Values = new double[] { translation.X, translation.Y, translation.Z },
                                sid = "t",
                            },
                            new rotate()
                            {
                                Values = new double[] { 1.0, 0.0, 0.0, rotations.X },
                                sid = "rx"
                            },
                            new rotate()
                            {
                                Values = new double[] { 0.0, 1.0, 0.0, rotations.Y },
                                sid = "ry"
                            },
                            new rotate()
                            {
                                Values = new double[] { 0.0, 0.0, 1.0, rotations.Z },
                                sid = "rz"
                            } 
                        },

                        instance_geometry = new instance_geometry[]
                        {
                            new instance_geometry()
                            {
                                url="#caseGeometry",
                                bind_material = new bind_material()
                                {
                                    technique_common = new instance_material[]
                                    {
                                        new instance_material() { symbol="materialCase0", target="#material_Case0_ID" },
                                        new instance_material() { symbol="materialCase1", target="#material_Case1_ID" },
                                        new instance_material() { symbol="materialCase2", target="#material_Case2_ID" },
                                        new instance_material() { symbol="materialCase3", target="#material_Case3_ID" },
                                        new instance_material() { symbol="materialCase4", target="#material_Case4_ID" },
                                        new instance_material() { symbol="materialCase5", target="#material_Case5_ID" },
                                        new instance_material() { symbol="materialCaseLines", target="#material_CaseLines_ID"}
                                    }
                                }
                            }
                        }
                    };
                    sceneNodes.Add(caseNode);

                    // animations
                    CreateAnimation(caseIndex, (uint)_palletSolution.CaseCount, listAnimationSource, bp);

                    // increment case index
                    ++caseIndex;
                }
            }

            // add nodes
            mainScene.node = sceneNodes.ToArray();

            animationMain.Items = listAnimationSource.ToArray();

            // library_cameras
            camera cameraCamera = new camera() { id = "Camera-Camera", name = "Camera-Camera" };
            cameraOpticsTechnique_commonPerspective cameraPerspective = new cameraOpticsTechnique_commonPerspective()
            {
                znear = new TargetableFloat() { sid = "znear", Value = 1.0 },
                zfar = new TargetableFloat() { sid = "zfar", Value = 10000.0 }
            };
            cameraCamera.optics = new cameraOptics() { technique_common = new cameraOpticsTechnique_common() { Item = cameraPerspective } };
            cameras.camera = new camera[] { cameraCamera };

            // colladaScene
            colladaScene.instance_visual_scene = new InstanceWithExtra() { url = "#MainScene" };

            model.Save(filePath);
            model.Save(System.IO.Path.ChangeExtension(filePath, "xml"));
        }
예제 #2
0
            public CL.node GetNode(int index, Matrix4x4 transform, string name)
            {
                var n = new CL.node();

                if (index != 0)
                {
                    name += "_lod" + index;
                }
                n.name  = n.id = name;
                n.Items = new object[] {
                    new CL.matrix()
                    {
                        sid  = "transform",
                        Text = MatrixText(transform)
                    }
                };
                n.ItemsElementName = new CL.ItemsChoiceType7[] {
                    CL.ItemsChoiceType7.matrix
                };
                n.instance_geometry = new CL.instance_geometry[] {
                    new CL.instance_geometry {
                        url           = "#" + Geometries[index].id,
                        bind_material = new CL.bind_material()
                        {
                            technique_common = GetMaterials(Geometries[index])
                        }
                    }
                };
                return(n);
            }
예제 #3
0
파일: Skeleton.cs 프로젝트: Norbyte/lslib
        public static Bone FromCollada(node bone, int parentIndex, List<Bone> bones, Dictionary<string, Bone> boneSIDs, Dictionary<string, Bone> boneIDs)
        {
            var transMat = ColladaHelpers.TransformFromNode(bone);
            var colladaBone = new Bone();
            colladaBone.TransformSID = transMat.TransformSID;
            var myIndex = bones.Count;
            bones.Add(colladaBone);
            boneSIDs.Add(bone.sid, colladaBone);
            if (bone.id != null)
            {
                boneIDs.Add(bone.id, colladaBone);
            }

            colladaBone.ParentIndex = parentIndex;
            colladaBone.Name = bone.name;
            colladaBone.LODError = 0; // TODO
            colladaBone.Transform = transMat.transform;
            colladaBone.UpdateInverseWorldTransform(bones);

            if (bone.node1 != null)
            {
                foreach (var node in bone.node1)
                {
                    if (node.type == NodeType.JOINT)
                    {
                        FromCollada(node, myIndex, bones, boneSIDs, boneIDs);
                    }
                }
            }

            return colladaBone;
        }
예제 #4
0
        static ColladaObject ProcessNode(CL.UpAxisType up, CL.library_geometries geom, CL.node n, CL.library_materials matlib, CL.library_effects fxlib)
        {
            var obj = new ColladaObject();

            obj.Name = n.name;
            obj.ID   = n.id;
            if (n.instance_geometry != null && n.instance_geometry.Length > 0)
            {
                //Geometry object
                if (n.instance_geometry.Length != 1)
                {
                    throw new Exception("How to handle multiple geometries/node?");
                }
                var uri = CheckURI(n.instance_geometry[0].url);
                var g   = geom.geometry.Where((x) => x.id == uri).First();
                if (g.Item is CL.mesh)
                {
                    obj.Geometry = GetGeometry(up, g, matlib, fxlib);
                }
                else if (g.Item is CL.spline)
                {
                    obj.Spline = GetSpline(up, g);
                }
            }
            if (n.Items.OfType <CL.matrix>().Any())
            {
                var tr = n.Items.OfType <CL.matrix>().First();
                obj.Transform = GetMatrix(up, tr.Text);
            }
            else
            {
                Matrix4x4 mat = Matrix4x4.Identity;
                foreach (var item in n.Items)
                {
                    if (item is CL.TargetableFloat3)
                    {
                        //var float3 =
                    }
                }
                obj.Transform = mat;
            }
            if (n.node1 != null && n.node1.Length > 0)
            {
                foreach (var node in n.node1)
                {
                    obj.Children.Add(ProcessNode(up, geom, node, matlib, fxlib));
                }
            }
            return(obj);
        }
예제 #5
0
파일: Skeleton.cs 프로젝트: Norbyte/lslib
 public static Skeleton FromCollada(node root)
 {
     var skeleton = new Skeleton();
     skeleton.Bones = new List<Bone>();
     skeleton.LODType = 0;
     skeleton.Name = root.name;
     skeleton.BonesBySID = new Dictionary<string, Bone>();
     skeleton.BonesByID = new Dictionary<string, Bone>();
     Bone.FromCollada(root, -1, skeleton.Bones, skeleton.BonesBySID, skeleton.BonesByID);
     return skeleton;
 }
예제 #6
0
파일: Skeleton.cs 프로젝트: Norbyte/lslib
        public node MakeCollada(string parentName)
        {
            var node = new node();
            node.id = "Bone_" + Name.Replace(' ', '_');
            node.name = Name; // .Replace(' ', '_');
            node.sid = Name.Replace(' ', '_');
            node.type = NodeType.JOINT;

            var transforms = new List<object>();
            var transformTypes = new List<ItemsChoiceType2>();

            if (false) // Separate transforms
            {
                var rotationX = new rotate();
                rotationX.sid = "RotateX";
                transforms.Add(rotationX);
                transformTypes.Add(ItemsChoiceType2.rotate);

                var rotationY = new rotate();
                rotationY.sid = "RotateY";
                transforms.Add(rotationY);
                transformTypes.Add(ItemsChoiceType2.rotate);

                var rotationZ = new rotate();
                rotationZ.sid = "RotateZ";
                transforms.Add(rotationZ);
                transformTypes.Add(ItemsChoiceType2.rotate);

                if ((Transform.Flags & (uint)Transform.TransformFlags.HasRotation) != 0)
                {
                    var rot = Transform.Rotation.Normalized();
                    //var x = Math.Atan2(2 * (rot.W * rot.X + rot.Y * rot.Z), 1 - 2 * (rot.X * rot.X + rot.Y * rot.Y));
                    //var y = Math.Asin(2 * (rot.W * rot.Y - rot.X * rot.Z));
                    //var z = Math.Atan2(2 * (rot.W * rot.Z + rot.X * rot.Y), 1 - 2 * (rot.Y * rot.Y + rot.Z * rot.Z));

                    //var x = Math.Atan2(2 * rot.Y * rot.W - 2 * rot.X * rot.Z, 1 - 2 * (rot.Y * rot.Y + rot.Z * rot.Z));
                    //var y = Math.Asin(2 * (rot.X * rot.Y + rot.Z * rot.W));
                    //var z = Math.Atan2(2 * rot.X * rot.W - 2 * rot.Y * rot.Z, 1 - 2 * (rot.X * rot.X + rot.Z * rot.Z));
                    var q = new float[] { rot.X, rot.Y, rot.Z, rot.W };

                    // sedris z-y-x
                    /*var x = Math.Atan2(q[2] * q[3] + q[0] * q[1], 0.5f - (q[1] * q[1] + q[2] * q[2]));
                    var y = Math.Asin(-2 * (q[1] * q[3] - q[0] * q[2]));
                    var z = Math.Atan2(q[1] * q[2] + q[0] * q[3], 0.5f - (q[2] * q[2] + q[3] * q[3]));*/

                    var sqw = rot.W * rot.W;
                    var sqx = rot.X * rot.X;
                    var sqy = rot.Y * rot.Y;
                    var sqz = rot.Z * rot.Z;
                    var x = Math.Atan2(2.0 * (rot.X * rot.Y + rot.Z * rot.W), (sqx - sqy - sqz + sqw));
                    var z = Math.Atan2(2.0 * (rot.Y * rot.Z + rot.X * rot.W), (-sqx - sqy + sqz + sqw));
                    var y = Math.Asin(-2.0 * (rot.X * rot.Z - rot.Y * rot.W) / (sqx + sqy + sqz + sqw));

                    rotationX.Values = new double[] { 1.0, 0.0, 0.0, x * 180 / Math.PI };
                    rotationY.Values = new double[] { 0.0, 1.0, 0.0, y * 180 / Math.PI };
                    rotationZ.Values = new double[] { 0.0, 0.0, 1.0, z * 180 / Math.PI };

                    var axisAngle = Transform.Rotation.ToAxisAngle();
                    //rotation.Values = new double[] { axisAngle.X, axisAngle.Y, axisAngle.Z, axisAngle.W * 180 / Math.PI };
                    //rotationX.Values = new double[] { axisAngle.X, 0.0, 0.0, axisAngle.W * 180 / Math.PI };
                    //rotationY.Values = new double[] { 0.0, axisAngle.Y, 0.0, axisAngle.W * 180 / Math.PI };
                    //rotationZ.Values = new double[] { 0.0, 0.0, axisAngle.Z, axisAngle.W * 180 / Math.PI };
                    /*rotationX.Values = new double[] { 1.0, 0.0, 0.0, axisAngle.X * axisAngle.W * 180 / Math.PI };
                    rotationY.Values = new double[] { 0.0, 1.0, 0.0, axisAngle.Y * axisAngle.W * 180 / Math.PI };
                    rotationZ.Values = new double[] { 0.0, 0.0, 1.0, axisAngle.Z * axisAngle.W * 180 / Math.PI };*/
                }
                else
                {
                    rotationX.Values = new double[] { 1.0, 0.0, 0.0, 0.0 };
                    rotationY.Values = new double[] { 0.0, 0.0, 0.0, 0.0 };
                    rotationZ.Values = new double[] { 0.0, 0.0, 0.0, 0.0 };
                }

                var scale = new TargetableFloat3();
                scale.sid = "Scale";
                transforms.Add(scale);
                transformTypes.Add(ItemsChoiceType2.scale);

                if ((Transform.Flags & (uint)Transform.TransformFlags.HasScaleShear) != 0)
                {
                    var scaleShear = Transform.ScaleShear.Diagonal;
                    scale.Values = new double[] { scaleShear.X, scaleShear.Y, scaleShear.Z };
                }
                else
                {
                    scale.Values = new double[] { 1.0, 1.0, 1.0 };
                }

                var translate = new TargetableFloat3();
                translate.sid = "Translate";
                transforms.Add(translate);
                transformTypes.Add(ItemsChoiceType2.translate);

                if ((Transform.Flags & (uint)Transform.TransformFlags.HasTranslation) != 0)
                {
                    var transVec = Transform.Translation;
                    translate.Values = new double[] { transVec.X, transVec.Y, transVec.Z };
                }
                else
                {
                    translate.Values = new double[] { 0.0, 0.0, 0.0 };
                }
            }
            else
            {
                var transform = new matrix();
                transform.sid = "Transform";
                var mat = Transform.ToMatrix4();
                mat.Transpose();
                transform.Values = new double[] {
                    mat[0, 0], mat[0, 1], mat[0, 2], mat[0, 3],
                    mat[1, 0], mat[1, 1], mat[1, 2], mat[1, 3],
                    mat[2, 0], mat[2, 1], mat[2, 2], mat[2, 3],
                    mat[3, 0], mat[3, 1], mat[3, 2], mat[3, 3] 
                };
                transforms.Add(transform);
                transformTypes.Add(ItemsChoiceType2.matrix);
            }

            node.Items = transforms.ToArray();
            node.ItemsElementName = transformTypes.ToArray();
            return node;
        }
예제 #7
0
        private node FindNodeInTree(node parent, string nodeID)
        {
            if (parent.id == null)
                return null;

            if (parent.id.Equals(nodeID))
            {
                return parent;
            }
            else if (parent.node1 != null && parent.node1.Length > 0)
            {
                foreach (node child in parent.node1)
                {
                    node result = FindNodeInTree(child, nodeID);
                    if (result != null)
                        return result;
                }
            }
            return null;
        }
예제 #8
0
        private static void ReadNodeTransformations(node nodeNODE, ref Vector3 nodeScale, ref Vector3 nodeRotation, ref Vector3 nodeTranslation)
        {
            List<Tuple<Vector3, TransformationType>> transforms = new List<Tuple<Vector3, TransformationType>>();
            bool matrixBacked = false;
            for (int i = 0; i < ((nodeNODE.Items != null) ? nodeNODE.Items.Length : 0); i++)
            {
                var item = nodeNODE.Items[i];

                if (nodeNODE.ItemsElementName[i].Equals(ItemsChoiceType2.matrix))
                {
                    Matrix4 nodeMatrix = Helper.DoubleArrayToMatrix4((item as matrix).Values);
                    Helper.DecomposeSRTMatrix1(nodeMatrix, out nodeScale, out nodeRotation, out nodeTranslation);
                    matrixBacked = true;
                }
                else
                {
                    if (nodeNODE.ItemsElementName[i].Equals(ItemsChoiceType2.translate))
                    {
                        var translate = item as TargetableFloat3;
                        Vector3 tmp = new Vector3((float)translate.Values[0], (float)translate.Values[1], (float)translate.Values[2]);
                        transforms.Add(new Tuple<Vector3, TransformationType>(tmp, TransformationType.TranslationXYZ));
                    }
                    else if (nodeNODE.ItemsElementName[i].Equals(ItemsChoiceType2.rotate))
                    {
                        /*
                         * <rotate sid="rotateZ">0 0 1 0</rotate>
                         * <rotate sid="rotateY">0 1 0 45</rotate>
                         * <rotate sid="rotateX">1 0 0 0</rotate>
                         */
                        var rotate = item as rotate;
                        TransformationType rotType = GetRotationType(rotate);
                        Vector3 rot = Vector3.Zero;
                        switch (rotType)
                        {
                            case TransformationType.RotationX:
                                rot = new Vector3((float)(rotate.Values[3] * Helper.Deg2Rad), 0.0f, 0.0f);
                                break;
                            case TransformationType.RotationY:
                                rot = new Vector3(0.0f, (float)(rotate.Values[3] * Helper.Deg2Rad), 0.0f);
                                break;
                            case TransformationType.RotationZ:
                                rot = new Vector3(0.0f, 0.0f, (float)(rotate.Values[3] * Helper.Deg2Rad));
                                break;
                        }
                        transforms.Add(new Tuple<Vector3, TransformationType>(rot, rotType));
                    }
                    else if (nodeNODE.ItemsElementName[i].Equals(ItemsChoiceType2.scale))
                    {
                        var scale = item as TargetableFloat3;
                        Vector3 tmp = new Vector3((float)scale.Values[0], (float)scale.Values[1], (float)scale.Values[2]);
                        transforms.Add(new Tuple<Vector3, TransformationType>(tmp, TransformationType.ScaleXYZ));
                    }
                }
            }
            if (!matrixBacked)
            {
                // If matrix not used, multiply each of the transformations in the reverse of the order they appear.
                // IMPORTANT NOTE: The order must be Scale, Rotation, Translation (appear in file TRzRyRxS)
                List<Tuple<Vector3, TransformationType>> scale =
                    transforms.Where(tran => tran.Item2.Equals(TransformationType.ScaleXYZ)).ToList();
                List<Tuple<Vector3, TransformationType>> rotate =
                    transforms.Where(tran => tran.Item2.Equals(TransformationType.RotationX) ||
                        tran.Item2.Equals(TransformationType.RotationY) || tran.Item2.Equals(TransformationType.RotationZ)).ToList();
                List<Tuple<Vector3, TransformationType>> translate =
                    transforms.Where(tran => tran.Item2.Equals(TransformationType.TranslationXYZ)).ToList();

                if (scale.Count <= 1 && rotate.Count <= 3 && translate.Count <= 1)
                {
                    // Making an assumption that the order is SRT if less than 5 tranformations, if it's greater than
                    // 5 or there are 5 but not in the order in above condition, use matrix decomposition method.
                    nodeScale = (scale.Count == 1) ? scale[0].Item1 : nodeScale;
                    foreach (Tuple<Vector3, TransformationType> rot in rotate)
                    {
                        if (rot.Item2 == TransformationType.RotationX)
                        {
                            nodeRotation.X = rot.Item1.X;
                        }
                        if (rot.Item2 == TransformationType.RotationY)
                        {
                            nodeRotation.Y = rot.Item1.Y;
                        }
                        if (rot.Item2 == TransformationType.RotationZ)
                        {
                            nodeRotation.Z = rot.Item1.Z;
                        }
                    }
                    nodeTranslation = (translate.Count == 1) ? translate[0].Item1 : nodeTranslation;
                }
                else
                {
                    // If not we need to multiply the matrices and then decompose the final matrix
                    Matrix4 result = Matrix4.Identity;
                    for (int i = transforms.Count - 1; i >= 0; i--)
                    {
                        Tuple<Vector3, TransformationType> current = transforms.ElementAt(i);
                        Vector3 vec = current.Item1;
                        switch (current.Item2)
                        {
                            case TransformationType.ScaleXYZ:
                                Matrix4 mscale = Matrix4.CreateScale(vec);
                                Matrix4.Mult(ref result, ref mscale, out result);
                                break;
                            case TransformationType.RotationX:
                                Matrix4 mxrot = Matrix4.CreateRotationX(vec.X);
                                Matrix4.Mult(ref result, ref mxrot, out result);
                                break;
                            case TransformationType.RotationY:
                                Matrix4 myrot = Matrix4.CreateRotationY(vec.Y);
                                Matrix4.Mult(ref result, ref myrot, out result);
                                break;
                            case TransformationType.RotationZ:
                                Matrix4 mzrot = Matrix4.CreateRotationZ(vec.Z);
                                Matrix4.Mult(ref result, ref mzrot, out result);
                                break;
                            case TransformationType.TranslationXYZ:
                                Matrix4 mtrans = Matrix4.CreateTranslation(vec);
                                Matrix4.Mult(ref result, ref mtrans, out result);
                                break;
                        }
                    }

                    Helper.DecomposeSRTMatrix1(result, out nodeScale, out nodeRotation, out nodeTranslation);
                }
            }
        }
예제 #9
0
 private static bool IsRootNodeOfChild(node parent, node child)
 {
     if (parent.node1 == null || parent.node1.Length == 0)
         return false;
     else
     {
         foreach (node n in parent.node1)
         {
             if (child.id.Equals(n.id))
                 return true;
             else if (IsRootNodeOfChild(child, n))
                 return true;
         }
     }
     return false;
 }
예제 #10
0
        private void ReadNode(node joint, node parent, bool inSkeleton)
        {
            string id = (joint.id != null ? joint.id : (joint.name != null ? joint.name : m_Model.m_BoneTree.Count.ToString()));

            Vector3 nodeScale = Vector3.One;
            Vector3 nodeRotation = Vector3.Zero;
            Vector3 nodeTranslation = Vector3.Zero;

            ReadNodeTransformations(joint, ref nodeScale, ref nodeRotation, ref nodeTranslation);

            if (joint.instance_geometry != null && joint.instance_geometry.Length > 0)
            {
                // Making an assumption that <instance_geometry> will never appear within a skeleton, not sure if it can?

                ModelBase.BoneDef rootBone = new ModelBase.BoneDef(id);

                rootBone.SetScale(nodeScale);
                rootBone.SetRotation(nodeRotation);
                rootBone.SetTranslation(nodeTranslation);

                m_Model.m_BoneTree.AddRootBone(rootBone);

                m_Model.m_BoneTransformsMap.Add(id, m_Model.m_BoneTree.GetBoneIndex(id));

                foreach (instance_geometry instanceGeometry in joint.instance_geometry)
                {
                    string geometryID = instanceGeometry.url.Replace("#", "");

                    Dictionary<string, string> bindMaterials = new Dictionary<string, string>();

                    if (instanceGeometry.bind_material != null)
                    {
                        foreach (instance_material instanceMaterial in instanceGeometry.bind_material.technique_common)
                        {
                            bindMaterials.Add(instanceMaterial.symbol, instanceMaterial.target.Replace("#", ""));
                        }
                    }

                    ModelBase.GeometryDef geometry = ReadGeometry(geometryID, id, bindMaterials);
                    rootBone.m_Geometries.Add(geometryID, geometry);
                }
            }
            else if (joint.instance_controller != null && joint.instance_controller.Length > 0)
            {
                // Making an assumption that <instance_controller> will never appear within a skeleton, not sure if it can?

                instance_controller instanceController = joint.instance_controller[0];

                string controllerID = instanceController.url.Replace("#", "");
                if (instanceController.skeleton != null && instanceController.skeleton.Length > 0)
                {

                    /*string skeletonRoot = null;
                    foreach (string skel in instanceController.skeleton)
                    {
                        string skeleton = skel.Replace("#", "");
                        if (skeletonRoot == null) skeletonRoot = skeleton;
                        if (m_Model.m_BoneTree.GetBoneByID(skeleton) != null) continue;

                        ReadSkeleton(skeletonRoot);
                    }
                    // WRONG */

                    string skeletonRoot = instanceController.skeleton[0].Replace("#", "");
                    ReadSkeleton(skeletonRoot);

                    controller cntl = this.library_controllers.controller.Where(cntl0 => cntl0.id.Equals(controllerID)).ElementAt(0);
                    if (cntl.Item as skin != null)
                    {
                        // Currently there is only support for skin controllers. Where a skin uses as its source another
                        // controller eg. a morph, we'll just recursively go through until we find a skin with a geometry
                        // as the source and return the geometry's ID.
                        // I've seen a skin use a skin as a source where the first skin gave joint indices of -1 from 3DS Max and
                        // OpenCOLLAD, in cases like this, we do as above and just take the geometry ID and attach the skin being
                        // read to that.
                        string skinSourceID = null;
                        var queue = new Queue<controller>();
                        queue.Enqueue(cntl);
                        while (queue.Count > 0)
                        {
                            controller cont = queue.Dequeue();
                            string srcID = (cont.Item as skin).source1.Replace("#", "");
                            if (this.library_geometries != null &&
                                this.library_geometries.geometry.Where(geom0 => geom0.id.Equals(srcID)).Count() < 1)
                            {
                                IEnumerable<controller> res = this.library_controllers.controller.Where(cont0 => cont0.id.Equals(srcID));
                                if (res.Count() > 0)
                                {
                                    queue.Enqueue(res.ElementAt(0));
                                }
                            }
                            else
                            {
                                skinSourceID = srcID;
                            }
                        }

                        m_Model.m_BoneTransformsMap.Clear();

                        int[] vertexBoneIDs = ReadSkinController(controllerID, skeletonRoot, skinSourceID);

                        Dictionary<string, string> bindMaterials = new Dictionary<string, string>();
                        if (instanceController.bind_material != null)
                        {
                            foreach (instance_material instanceMaterial in instanceController.bind_material.technique_common)
                            {
                                bindMaterials.Add(instanceMaterial.symbol, instanceMaterial.target.Replace("#", ""));
                            }
                        }

                        ModelBase.GeometryDef geomDef = ReadGeometry(skinSourceID, skeletonRoot, bindMaterials, vertexBoneIDs);
                        m_Model.m_BoneTree.GetBoneByID(skeletonRoot).m_Geometries.Add(skinSourceID, geomDef);
                    }
                }
            }
            else if (inSkeleton)
            {
                ModelBase.BoneDef boneDef = new ModelBase.BoneDef(joint.id);

                if (joint == parent)
                {
                    m_Model.m_BoneTree.AddRootBone(boneDef);
                }
                else
                {
                    ModelBase.BoneDef parentBone = m_Model.m_BoneTree.GetBoneByID(parent.id);
                    parentBone.AddChild(boneDef);
                }

                boneDef.SetScale(nodeScale);
                boneDef.SetRotation(nodeRotation);
                boneDef.SetTranslation(nodeTranslation);

                if (joint.node1 == null || joint.node1.Length == 0)
                    return;
                foreach (node child in joint.node1)
                {
                    if (child.type.Equals(NodeType.NODE))
                    {
                        Console.WriteLine("Warning: node: " + joint.id + " has a child of type \"NODE\" within a skeleton, failure likely");
                    }

                    ReadNode(child, joint, true);
                }
            }
        }
예제 #11
0
 protected node AddToCollada(List<material> materials, List<effect> effects, List<geometry> geometries,
     List<string> visitedAttaches, bool hasTextures)
 {
     BasicAttach attach = Attach as BasicAttach;
     if (attach == null || visitedAttaches.Contains(attach.Name))
         goto skipAttach;
     visitedAttaches.Add(attach.Name);
     int m = 0;
     foreach (NJS_MATERIAL item in attach.Material)
     {
         materials.Add(new material
         {
             id = "material_" + attach.Name + "_" + m,
             name = "material_" + attach.Name + "_" + m,
             instance_effect = new instance_effect
             {
                 url = "#" + "material_" + attach.Name + "_" + m + "_eff"
             }
         });
         if (hasTextures & item.UseTexture)
         {
             effects.Add(new effect
             {
                 id = "material_" + attach.Name + "_" + m + "_eff",
                 name = "material_" + attach.Name + "_" + m + "_eff",
                 Items = new effectFx_profile_abstractProfile_COMMON[]
                 {
                     new effectFx_profile_abstractProfile_COMMON
                     {
                         Items = new object[]
                         {
                             new common_newparam_type
                             {
                                 sid = "material_" + attach.Name + "_" + m + "_eff_surface",
                                 /*Item = new Collada141.fx_sampler2D_common()
                                  { instance_image = new Collada141.instance_image() { url = "#image_" + (item.TextureID + 1).ToString(System.Globalization.NumberFormatInfo.InvariantInfo) } },
                                  ItemElementName = Collada141.ItemChoiceType.sampler2D*/
                                 Item = new fx_surface_common
                                 {
                                     type = fx_surface_type_enum.Item2D,
                                     init_from =
                                         new fx_surface_init_from_common[]
                                         {
                                             new fx_surface_init_from_common
                                             {
                                                 Value = "image_" + (item.TextureID + 1).ToString(NumberFormatInfo.InvariantInfo)
                                             }
                                         }
                                 },
                                 ItemElementName = ItemChoiceType.surface
                             }
                         },
                         technique = new effectFx_profile_abstractProfile_COMMONTechnique
                         {
                             sid = "standard",
                             Item = new effectFx_profile_abstractProfile_COMMONTechniquePhong
                             {
                                 ambient = new common_color_or_texture_type
                                 {
                                     Item = new common_color_or_texture_typeTexture
                                     {
                                         texture = "material_" + attach.Name + "_" + m + "_eff_surface",
                                         texcoord = "CHANNEL0"
                                     }
                                 },
                                 diffuse = new common_color_or_texture_type
                                 {
                                     Item = new common_color_or_texture_typeColor
                                     {
                                         Values =
                                             new double[]
                                             {
                                                 item.DiffuseColor.R / 255d, item.DiffuseColor.G / 255d, item.DiffuseColor.B / 255d,
                                                 item.UseAlpha ? item.DiffuseColor.A / 255d : 1
                                             }
                                     }
                                 }
                             }
                         }
                     }
                 }
             });
         }
         else
         {
             effects.Add(new effect
             {
                 id = "material_" + attach.Name + "_" + m + "_eff",
                 name = "material_" + attach.Name + "_" + m + "_eff",
                 Items = new effectFx_profile_abstractProfile_COMMON[]
                 {
                     new effectFx_profile_abstractProfile_COMMON
                     {
                         technique = new effectFx_profile_abstractProfile_COMMONTechnique
                         {
                             sid = "standard",
                             Item = new effectFx_profile_abstractProfile_COMMONTechniquePhong
                             {
                                 diffuse = new common_color_or_texture_type
                                 {
                                     Item = new common_color_or_texture_typeColor
                                     {
                                         Values =
                                             new double[]
                                             {
                                                 item.DiffuseColor.R / 255d, item.DiffuseColor.G / 255d, item.DiffuseColor.B / 255d,
                                                 item.UseAlpha ? item.DiffuseColor.A / 255d : 1
                                             }
                                     }
                                 }
                             }
                         }
                     }
                 }
             });
         }
         m++;
     }
     List<double> verts = new List<double>();
     foreach (Vertex item in attach.Vertex)
     {
         verts.Add(item.X);
         verts.Add(item.Y);
         verts.Add(item.Z);
     }
     source pos = new source
     {
         id = attach.Name + "_position",
         Item = new float_array
         {
             id = attach.Name + "_position_array",
             count = (ulong)verts.Count,
             Values = verts.ToArray()
         },
         technique_common = new sourceTechnique_common
         {
             accessor = new accessor
             {
                 source = "#" + attach.Name + "_position_array",
                 count = (ulong)(verts.Count / 3),
                 stride = 3,
                 param =
                     new param[]
                     {
                         new param { name = "X", type = "float" }, new param { name = "Y", type = "float" },
                         new param { name = "Z", type = "float" }
                     }
             }
         }
     };
     verts = new List<double>();
     foreach (Vertex item in attach.Normal)
     {
         verts.Add(item.X);
         verts.Add(item.Y);
         verts.Add(item.Z);
     }
     source nor = new source
     {
         id = attach.Name + "_normal",
         Item = new float_array
         {
             id = attach.Name + "_normal_array",
             count = (ulong)verts.Count,
             Values = verts.ToArray()
         },
         technique_common = new sourceTechnique_common
         {
             accessor = new accessor
             {
                 source = "#" + attach.Name + "_normal_array",
                 count = (ulong)(verts.Count / 3),
                 stride = 3,
                 param =
                     new param[]
                     {
                         new param { name = "X", type = "float" }, new param { name = "Y", type = "float" },
                         new param { name = "Z", type = "float" }
                     }
             }
         }
     };
     List<source> srcs = new List<source> { pos, nor };
     foreach (NJS_MESHSET mitem in attach.Mesh)
     {
         if (mitem.UV != null)
         {
             verts = new List<double>();
             foreach (UV item in mitem.UV)
             {
                 verts.Add(item.U);
                 verts.Add(-item.V);
             }
             srcs.Add(new source
             {
                 id = mitem.UVName,
                 Item = new float_array
                 {
                     id = mitem.UVName + "_array",
                     count = (ulong)verts.Count,
                     Values = verts.ToArray()
                 },
                 technique_common = new sourceTechnique_common
                 {
                     accessor = new accessor
                     {
                         source = "#" + mitem.UVName + "_array",
                         count = (ulong)(verts.Count / 2),
                         stride = 2,
                         param = new param[] { new param { name = "S", type = "float" }, new param { name = "T", type = "float" } }
                     }
                 }
             });
         }
     }
     List<triangles> tris = new List<triangles>();
     foreach (NJS_MESHSET mesh in attach.Mesh)
     {
         bool hasVColor = mesh.VColor != null;
         bool hasUV = mesh.UV != null;
         uint currentstriptotal = 0;
         foreach (Poly poly in mesh.Poly)
         {
             List<uint> inds = new List<uint>();
             switch (mesh.PolyType)
             {
                 case Basic_PolyType.Triangles:
                     for (uint i = 0; i < 3; i++)
                     {
                         inds.Add(poly.Indexes[i]);
                         if (hasUV)
                             inds.Add(currentstriptotal + i);
                     }
                     currentstriptotal += 3;
                     break;
                 case Basic_PolyType.Quads:
                     for (uint i = 0; i < 3; i++)
                     {
                         inds.Add(poly.Indexes[i]);
                         if (hasUV)
                             inds.Add(currentstriptotal + i);
                     }
                     for (uint i = 1; i < 4; i++)
                     {
                         inds.Add(poly.Indexes[i]);
                         if (hasUV)
                             inds.Add(currentstriptotal + i);
                     }
                     currentstriptotal += 4;
                     break;
                 case Basic_PolyType.NPoly:
                 case Basic_PolyType.Strips:
                     bool flip = !((Strip)poly).Reversed;
                     for (int k = 0; k < poly.Indexes.Length - 2; k++)
                     {
                         flip = !flip;
                         if (!flip)
                         {
                             for (uint i = 0; i < 3; i++)
                             {
                                 inds.Add(poly.Indexes[k + i]);
                                 if (hasUV)
                                     inds.Add(currentstriptotal + i);
                             }
                         }
                         else
                         {
                             inds.Add(poly.Indexes[k + 1]);
                             if (hasUV)
                                 inds.Add(currentstriptotal + 1);
                             inds.Add(poly.Indexes[k]);
                             if (hasUV)
                                 inds.Add(currentstriptotal);
                             inds.Add(poly.Indexes[k + 2]);
                             if (hasUV)
                                 inds.Add(currentstriptotal + 2);
                         }
                         currentstriptotal += 1;
                     }
                     currentstriptotal += 2;
                     break;
             }
             string[] indstr = new string[inds.Count];
             for (int i = 0; i < inds.Count; i++)
                 indstr[i] = inds[i].ToString(NumberFormatInfo.InvariantInfo);
             List<InputLocalOffset> inp = new List<InputLocalOffset>
             {
                 new InputLocalOffset { semantic = "VERTEX", offset = 0, source = "#" + attach.Name + "_vertices" }
             };
             if (hasUV)
             {
                 inp.Add(new InputLocalOffset
                 {
                     semantic = "TEXCOORD",
                     offset = 1,
                     source = "#" + mesh.UVName,
                     setSpecified = true
                 });
             }
             tris.Add(new triangles
             {
                 material = "material_" + attach.Name + "_" + mesh.MaterialID,
                 count = (ulong)(inds.Count / (hasUV ? 6 : 3)),
                 input = inp.ToArray(),
                 p = string.Join(" ", indstr)
             });
         }
     }
     geometries.Add(new geometry
     {
         id = attach.Name,
         name = attach.Name,
         Item = new mesh
         {
             source = srcs.ToArray(),
             vertices = new vertices
             {
                 id = attach.Name + "_vertices",
                 input = new InputLocal[]
                 {
                     new InputLocal
                     {
                         semantic = "POSITION",
                         source = "#" + attach.Name + "_position"
                     },
                     new InputLocal
                     {
                         semantic = "NORMAL",
                         source = "#" + attach.Name + "_normal"
                     }
                 }
             },
             Items = tris.ToArray()
         }
     });
     skipAttach:
     node node = new node
     {
         id = Name,
         name = Name,
         Items = new object[]
         {
             new TargetableFloat3 { sid = "translate", Values = new double[] { Position.X, Position.Y, Position.Z } },
             new rotate { sid = "rotateZ", Values = new double[] { 0, 0, 1, Rotation.ZDeg } },
             new rotate { sid = "rotateX", Values = new double[] { 1, 0, 0, Rotation.XDeg } },
             new rotate { sid = "rotateY", Values = new double[] { 0, 1, 0, Rotation.YDeg } },
             new TargetableFloat3 { sid = "scale", Values = new double[] { Scale.X, Scale.Y, Scale.Z } }
         },
         ItemsElementName = new ItemsChoiceType2[]
         {
             ItemsChoiceType2.translate,
             ItemsChoiceType2.rotate,
             ItemsChoiceType2.rotate,
             ItemsChoiceType2.rotate,
             ItemsChoiceType2.scale
         }
     };
     if (attach != null)
     {
         List<instance_material> mats = new List<instance_material>();
         foreach (NJS_MESHSET item in attach.Mesh)
         {
             mats.Add(new instance_material
             {
                 symbol = "material_" + attach.Name + "_" + item.MaterialID,
                 target = "#" + "material_" + attach.Name + "_" + item.MaterialID
             });
         }
         node.instance_geometry = new instance_geometry[]
         {
             new instance_geometry
             {
                 url = "#" + attach.Name,
                 bind_material = new bind_material { technique_common = mats.ToArray() }
             }
         };
     }
     List<node> childnodes = new List<node>();
     foreach (NJS_OBJECT item in Children)
         childnodes.Add(item.AddToCollada(materials, effects, geometries, visitedAttaches, hasTextures));
     node.node1 = childnodes.ToArray();
     return node;
 }
예제 #12
0
        public static TransformMatrix TransformFromNode(node node)
        {
            var transform = new TransformMatrix
            {
                matrix = Matrix4.Identity,
                transform = new Transform(),
                TransformSID = null
            };

            if (node.ItemsElementName != null)
            {
                for (int i = 0; i < node.ItemsElementName.Length; i++)
                {
                    var name = node.ItemsElementName[i];
                    var item = node.Items[i];

                    switch (name)
                    {
                        case ItemsChoiceType2.translate:
                            {
                                var translation = item as TargetableFloat3;
                                ApplyTranslation(transform, translation);
                                break;
                            }

                        case ItemsChoiceType2.rotate:
                            {
                                var rotation = item as rotate;
                                ApplyRotation(transform, rotation);
                                break;
                            }

                        case ItemsChoiceType2.scale:
                            {
                                var scale = item as TargetableFloat3;
                                ApplyScale(transform, scale);
                                break;
                            }

                        case ItemsChoiceType2.matrix:
                            {
                                var mat = item as matrix;
                                transform.TransformSID = mat.sid;
                                ApplyMatrixTransform(transform, mat);
                                break;
                            }
                    }
                }
            }

            return transform;
        }
예제 #13
0
        static ColladaObject ProcessNode(CL.UpAxisType up, CL.library_geometries geom, CL.node n)
        {
            var obj = new ColladaObject();

            obj.Name = n.name;
            obj.ID   = n.id;
            if (n.instance_geometry != null && n.instance_geometry.Length > 0)
            {
                //Geometry object
                if (n.instance_geometry.Length != 1)
                {
                    throw new Exception("How to handle multiple geometries/node?");
                }
                var uri = CheckURI(n.instance_geometry[0].url);
                var g   = geom.geometry.Where((x) => x.id == uri).First();
                if (g.Item is CL.mesh)
                {
                    obj.Geometry = GetGeometry(up, g);
                }
                else if (g.Item is CL.spline)
                {
                    obj.Spline = GetSpline(up, g);
                }
            }
            if (n.Items.OfType <CL.matrix>().Any())
            {
                var tr = n.Items.OfType <CL.matrix>().First();
                obj.Transform = GetMatrix(tr.Text);
            }
            else
            {
                //TODO: Non-matrix transforms
            }
            if (n.node1 != null && n.node1.Length > 0)
            {
                foreach (var node in n.node1)
                {
                    obj.Children.Add(ProcessNode(up, geom, node));
                }
            }
            return(obj);
        }