示例#1
0
		public static void Raw_StoredProcedure( IKLink link )
		{
			Console.WriteLine( "\n===== Invoking a Stored Procedure through a Raw Command..." );

			// Inserting an employee through a stored procedure...
			var cmd = link.Raw(
				"EXEC employee_insert @FirstName = {0}, @LastName = {1}",
				"James", "Bond" );
			Console.WriteLine( "\n> Command => {0}", cmd );

			object[] list = cmd.ToArray();
			foreach( var obj in list ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();

			// Deleting to leave everything as it was...
			foreach( var obj in list ) {
				dynamic d = obj;
				string id = d.Id; // We are implicitly using the default table...

				var delete = link.Raw( "DELETE FROM Employees WHERE Id = {0}", id );
				Console.WriteLine( "\n> Command => {0}", delete );

				int n = delete.Execute();
				Console.WriteLine( "\n> Result => {0}", n );

				delete.Dispose();
			}
		}
示例#2
0
		public static Region Test_FindRegion( IKLink link, string id )
		{
			Console.WriteLine( "\n===== Finding a given region..." ); Console.ReadLine();
			Region reg = link.Find<Region>( x => x.Id == id );
			Console.WriteLine( "\n> Found Region: {0}", reg );
			return reg;
		}
示例#3
0
		public static void Test_Cache_Unicity( IKLink link, Region reg )
		{
			Console.WriteLine( "\n===== Testing unicity of the cache..." ); Console.ReadLine();
			Region neo = link.Find<Region>( x => x.Id == reg.Id );
			Console.WriteLine( "\n> New Region: {0}", neo );
			Console.WriteLine( "\n>> Same entity?: {0}", object.ReferenceEquals( reg, neo ) );
		}
示例#4
0
 public void FromIKLink(IKLink link)
 {
     Bone    = link.Bone;
     IsLimit = link.IsLimit;
     Low     = link.Low;
     High    = link.High;
     Euler   = link.Euler;
 }
示例#5
0
		public static Region Test_Insert( IKLink link )
		{
			Console.WriteLine( "\n===== Inserting a region ..." ); Console.ReadLine();
			Region reg = new Region() { Id = "XXX", ParentId = "200" };
			reg = link.Insert( reg ).Execute();
			Console.WriteLine( "\n>> Inserted Region: {0}", reg );
			return reg;
		}
示例#6
0
		public static void Raw_Query( IKLink link )
		{
			Console.WriteLine( "\n===== Raw Query..." );

			var cmd = link.Raw( "SELECT * FROM Employees WHERE BirthDate >= {0}", new CalendarDate( 1969, 1, 1 ) );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#7
0
		// Use this method to specify the test(s) to run...
		public static void Dispatcher( IKLink link )
		{
			Console.WriteLine( "\n===== Creating the maps..." ); Console.ReadLine();
			KMaps.StartCollector( 2500, true ); // Just for DEBUG purposes
			var map = new KMap<Region>( link, x => x.Regions ); map.Validate();

			var reg = Test_Insert( link );
			Test_Update( link, reg );
			Test_Delete( link, reg );
		}
示例#8
0
        // ReSharper disable once InconsistentNaming
        private void WriteIKLink([NotNull] IKLink link)
        {
            _writer.WriteInt32AsVarLenInt(link.BoneIndex, BoneElementSize);
            _writer.Write(link.IsLimited);

            if (link.IsLimited)
            {
                _writer.Write(link.LowerBound);
                _writer.Write(link.UpperBound);
            }
        }
示例#9
0
		public static void Raw_Query_MultipleTables( IKLink link )
		{
			Console.WriteLine( "\n===== Raw Query with Multiple Tables..." );
			var cmd = link.Raw(
				"SELECT * FROM Employees AS Emp, Countries as Ctry WHERE Emp.BirthDate >= {0} AND Emp.CountryId = Ctry.Id",
				new CalendarDate( 1969, 1, 1 ) );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#10
0
		public static void Raw_Delete_JamesBond_NonEnumerate( IKLink link )
		{
			Console.WriteLine( "\n===== Raw Delete James Bond but with no Enumeration..." );

			var cmd = link.Raw( "DELETE FROM Employees WHERE Id = {0}", "007" );
			Console.WriteLine( "\n> Command => {0}", cmd );

			int n = cmd.Execute();
			Console.WriteLine( "\n> Result => {0}", n );

			cmd.Dispose();
		}
示例#11
0
		/// <summary>
		/// Creates a new <see cref="KCommandDelete"/> instance associating it to the given link for the table given.
		/// <para>The dynamic lambda specification for the table should have the form "x => x.Table".</para>
		/// </summary>
		/// <param name="link">The link this command will be associated to.</param>
		/// <param name="table">The table this command refers to.</param>
		public KCommandDelete( IKLink link, Func<dynamic, object> table ) : base( link )
		{
			DEBUG.IndentLine( "\n-- KCommandDelete( Link, Table=?? )" );

			_TableAliasList = new KTableAliasList( Link.DbCaseSensitiveNames );

			if( table == null ) throw new ArgumentNullException( "Table" );
			_TextTable = Parser.Parse( table, rawstr: true );
			_TextTable = _TextTable.Validated( "Table", invalidChars: TypeHelper.InvalidNameChars );
			DEBUG.WriteLine( "\n-- Table: {0}", _TextTable );

			DEBUG.Unindent();
		}
示例#12
0
		public static void Raw_Insert_JamesBond_Enumerate( IKLink link )
		{
			Console.WriteLine( "\n===== Raw Insert James Bond with Enumerate..." );

			// Note that to enumerate in a non-SELECT Raw command, we need to explicitly include "OUTPUT INSERTED.*"...
			var cmd = link.Raw(
				"INSERT INTO Employees ( Id, FirstName, LastName, CountryId, BirthDate, JoinDate, Photo )"
				+ " OUTPUT INSERTED.*"
				+ " VALUES ( {0}, {1}, {2}, {3}, {4}, {5}, {6} )",
				"007", "James", "Bond", "uk", new CalendarDate( 1969, 1, 1 ), null, new byte[] { 0, 0, 7 } );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#13
0
        private IKLink ReadIKLink()
        {
            var link = new IKLink();

            link.BoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
            link.IsLimited = _reader.ReadBoolean();

            if (link.IsLimited)
            {
                link.LowerBound = _reader.ReadVector3();
                link.UpperBound = _reader.ReadVector3();
            }

            return(link);
        }
示例#14
0
        public void FromStreamEx(Stream s, PmxElementFormat f = null)
        {
            Target    = PmxStreamHelper.ReadElement_Int32(s, f.BoneSize);
            LoopCount = PmxStreamHelper.ReadElement_Int32(s);
            Angle     = PmxStreamHelper.ReadElement_Float(s);
            int num = PmxStreamHelper.ReadElement_Int32(s);

            LinkList.Clear();
            LinkList.Capacity = num;
            for (int i = 0; i < num; i++)
            {
                IKLink iKLink = new IKLink();
                iKLink.FromStreamEx(s, f);
                LinkList.Add(iKLink);
            }
        }
示例#15
0
        private PmxIK ReadPmxIK()
        {
            var ik = new PmxIK();

            ik.TargetBoneIndex = _reader.ReadVarLenIntAsInt32(BoneElementSize);
            ik.LoopCount       = _reader.ReadInt32();
            ik.AngleLimit      = _reader.ReadSingle();

            var linkCount = _reader.ReadInt32();
            var ikLinks   = new IKLink[linkCount];

            for (var i = 0; i < linkCount; ++i)
            {
                ikLinks[i] = ReadIKLink();
            }

            ik.Links = ikLinks;

            return(ik);
        }
示例#16
0
		static void _Nested_Readers_Employees( IKLink link, CountryTable ctry )
		{
			var cmd = link.From( x => x.Employees ).Where( x => x.CountryId == ctry.Id );
			DEBUG.IndentLine( "\n> Command => {0}", cmd );

			foreach( var emp in cmd.ConvertBy( rec => {
				EmployeeTable table = new EmployeeTable(); dynamic d = rec;
				table.Id = d.Id;
				table.FirstName = d.FirstName;
				table.LastName = d.LastName;
				table.CountryId = d.CountryId;

				ctry.Employees.Add( table );
				return table;
			} ) ) DEBUG.WriteLine( "\n> Employee => {0}", emp );
			cmd.Dispose();

			DEBUG.Unindent();
		}
示例#17
0
		public static void Nested_Readers( IKLink link )
		{
			Console.WriteLine( "\n===== Nested readers..." );

			var cmd = link.From( x => x.Countries ).OrderBy( x => x.Name );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var ctry in cmd.ConvertBy( rec => {
				CountryTable table = new CountryTable(); dynamic d = rec;
				table.Id = d.Id;
				table.Name = d.Name;
				table.RegionId = d.RegionId;

				_Nested_Readers_Employees( link, table );
				return table;
			} ) ) Console.WriteLine( "\n> Country => {0}", ctry );
			cmd.Dispose();
		}
示例#18
0
		public static void Query_GettingOneValue( IKLink link )
		{
			Console.WriteLine( "\n===== Query getting one value instead of a record..." );

			// As anonymous columns are not supported, we need to give a name to it
			// The easiest way is by using an alias for the object returned by the database

			var cmd = link
				.From( x => x.Employees )
				.Select( x => x.Count( x.Id ).As( x.SumOfEmployees ) );
			Console.WriteLine( "\n> Command => {0}", cmd );

			dynamic obj = cmd.First();
			Console.WriteLine( "\n> Using the record => {0}", obj );
			Console.WriteLine( "\n> Using the property => {0}", obj.SumOfEmployees );

			cmd.Dispose();
		}
示例#19
0
		public static void WithTransaction( IKLink link, params Action<IKLink>[] actions )
		{
			try {
				Console.WriteLine( "\n===== Transaction started..." );
				link.TransactionStart();
				foreach( var action in actions ) action( link );
				link.TransactionCommit();
				Console.WriteLine( "\n===== Transaction committed..." );
			}
			catch { link.TransactionAbort(); throw; }
		}
示例#20
0
		static void _Nested_UpdateReaders_Employees( IKLink link )
		{
			var cmd = link.Update( x => x.Employees )
				.Where( x => x.CountryId == "es" )
				.Column( x => x.CountryId = "es#" );
			DEBUG.IndentLine( "\n> Command => {0}", cmd );

			foreach( var emp in cmd.ConvertBy( rec => {
				EmployeeTable table = new EmployeeTable(); dynamic d = rec;
				table.Id = d.Id;
				table.FirstName = d.FirstName;
				table.LastName = d.LastName;
				table.CountryId = d.CountryId;

				return table;
			} ) ) DEBUG.WriteLine( "\n> Employee => {0}", emp );

			cmd.Dispose();
			DEBUG.Unindent();
		}
示例#21
0
		public static void Fake_Query_Extended_Syntax( IKLink link )
		{
			Console.WriteLine( "\n== A fake query to show the extended syntax usage..." );

			var cmd = link
				.From( "Employees AS Emp" )
				.GroupBy( x => x.Cube( x.C1, "C2 with Embedded Spaces" ) )
				.OrderBy( x => x( x.C3, "Text without meaning", x.C4 >= 9 ) )
				.Select( "C5 as C6" );

			Console.WriteLine( "\n> Command => {0}", cmd );
			Console.WriteLine( "\n> NOT EXECUTED AS IT HAS NO MEANING ..." );
		}
示例#22
0
		public static void Query_Basic_ConversionToAnonymous( IKLink link )
		{
			Console.WriteLine( "\n===== Basic Query with conversion to anonymous..." );

			var cmd = link.From( x => x.Employees.As( x.Emp ) ).Where( x => x.LastName >= "C" );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd.ConvertBy( rec => {
				// Using several ways of accessing the columns...
				dynamic d = rec;
				return new {
					d.Id,
					Name = string.Format( "{0}, {1}", rec["LastName"], rec["Emp", "FirstName"] )
				};
			} ) ) Console.WriteLine( "\n> Converted => {0}", obj );

			cmd.Dispose();
		}
示例#23
0
		public static void Query_WithChainedFroms( IKLink link )
		{
			Console.WriteLine( "\n===== Query using a chained From syntax..." );

			var cmd = link
				.From( x => x.Regions.As( x.Super ) ).Where( x => x.Super.Name == "Europe, Middle East & Africa" )
				.From( x => x.Regions.As( x.Reg ) ).Where( x => x.Reg.ParentId == x.Super.Id )
				.From( x => x.Countries.As( x.Ctry ) ).Where( x => x.Ctry.RegionId == x.Reg.Id )
				.From( x => x.Employees.As( x.Emp ) ).Where( x => x.Emp.CountryId == x.Ctry.Id )
				.Select( x => x.Emp.All() )
				.Select( x => x.Reg.All() )
				.OrderBy( x => x.Reg.Id ).OrderBy( x => x.Emp.Id );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#24
0
		public static void Query_With_In_and_Equal( IKLink link )
		{
			Console.WriteLine( "\n===== Query using the IN and EQUAL syntax..." );

			var cmd = link
				.From( x => x.Employees ).Where( x => !x.CountryId.In(
					link.From( y => y.Countries ).Select( y => y.Id ).Where( y => y.RegionId.In(
						link.From( z => z.Regions ).Select( z => z.Id ).Where( z => z.ParentId =
							link.From( p => p.Regions ).Select( p => p.Id )
							.Where( p => p.Name == "Europe, Middle East & Africa" )
				) ) ) ) );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#25
0
		public static void Query_WithSourceFroms( IKLink link )
		{
			Console.WriteLine( "\n===== Query using a command as the From source..." );

			var cmd = link
				.From(
					link.From( x => x.Countries.As( x.Ctry ) ).Where( x => x.Ctry.Id == "us" ),
					x => x.Location )
				.From( x => x.Employees.As( x.Emp ) ).Where( x => x.Emp.CountryId == x.Location.Id )
				.Select( x => x.Emp.All() );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#26
0
		public static void Query_MultipleTables_AndSkipTake( IKLink link )
		{
			Console.WriteLine( "\n===== Query multiples tables..." );

			var cmd = link
				.From( x => x.Employees.As( x.Emp ) ).Where( x => x.Emp.JoinDate >= new CalendarDate( 2000, 1, 1 ) )
				.From( x => x.Countries.As( x.Ctry ) ).Where( x => x.Ctry.Id == x.Emp.CountryId )
				.Select( x => x.Ctry.All() )
				.Select( x => x.Emp.Id, x => x.Emp.BirthDate, x => x.Emp.LastName );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );

			Console.WriteLine( "\n===== Query multiples tables with skip/take..." );

			foreach( var obj in cmd.SkipTake( 2, 2 ) )
				Console.WriteLine( "\n> Record => {0}", obj );

			cmd.Dispose();
		}
示例#27
0
		public static void Nested_UpdateReaders( IKLink link )
		{
			Console.WriteLine( "\n===== Nested Updates..." );

			KCommandRaw raw = link.Raw();
			Console.WriteLine( "\n== SUSPENDING THE CONSTRAINTS..." );
			raw.Set( "ALTER TABLE Countries NOCHECK CONSTRAINT ALL" ); raw.Execute();
			raw.Set( "ALTER TABLE Employees NOCHECK CONSTRAINT ALL" ); raw.Execute();

			var cmd = link.Update( x => x.Countries )
				.Where( x => x.Id == "es" )
				.Column( x => x.Id = "es#" );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var ctry in cmd.ConvertBy( rec => {
				CountryTable table = new CountryTable(); dynamic d = rec;
				table.Id = d.Id;
				table.Name = d.Name;
				table.RegionId = d.RegionId;

				_Nested_UpdateReaders_Employees( link );
				return table;
			} ) ) Console.WriteLine( "\n> Country => {0}", ctry );
			cmd.Dispose();

			Console.WriteLine( "\n== REACTIVATING THE CONSTRAINTS..." );
			raw.Set( "ALTER TABLE Countries CHECK CONSTRAINT ALL" ); raw.Execute();
			raw.Set( "ALTER TABLE Employees CHECK CONSTRAINT ALL" ); raw.Execute();
		}
示例#28
0
		public static void Query_Basic_WithIndexedColumns( IKLink link )
		{
			Console.WriteLine( "\n===== Basic Query with Indexed columns..." );

			var cmd = link.From( x => x.Employees.As( x.Emp ) ).Where( x => x.LastName >= "C" );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( KRecord obj in cmd )
				Console.WriteLine( "\n> Generated => {0}: {1} {2}",
					obj["Id"],
					obj["Emp", "FirstName"],
					obj["Employees", "LastName"] );

			cmd.Dispose();
		}
示例#29
0
		public static void Update_Enumerate( IKLink link )
		{
			Console.WriteLine( "\n===== Update enumerating the results..." );

			var cmd = link.Update( x => x.Employees )
				.Where( x => x.FirstName >= "E" )
				.Column(
					x => x.ManagerId = null,
					x => x.LastName = x.LastName + "_1",
					x => x.Photo = new byte[] { 99, 98, 97, 96 }
				);
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#30
0
        private static IReadOnlyList <PmxBone> AddBones([NotNull] Avatar combinedAvatar, [NotNull] Mesh combinedMesh, [NotNull, ItemNotNull] IReadOnlyList <PmxVertex> vertices)
        {
            var boneCount = combinedAvatar.AvatarSkeleton.NodeIDs.Length;
            var bones     = new List <PmxBone>(boneCount);

            var hierachy = BoneUtils.BuildBoneHierarchy(combinedAvatar);

            for (var i = 0; i < boneCount; ++i)
            {
                var bone      = new PmxBone();
                var transform = combinedAvatar.AvatarSkeletonPose.Transforms[i];
                var boneNode  = hierachy[i];

                var pmxBoneName = BoneUtils.GetPmxBoneName(boneNode.Path);

                bone.Name        = pmxBoneName;
                bone.NameEnglish = BoneUtils.TranslateBoneName(pmxBoneName);

                // PMX's bone positions are in world coordinate system.
                // Unity's are in local coords.
                bone.InitialPosition = boneNode.InitialPositionWorld;
                bone.CurrentPosition = bone.InitialPosition;

                bone.ParentIndex = boneNode.Parent?.Index ?? -1;
                bone.BoneIndex   = i;

                var singleDirectChild = GetDirectSingleChildOf(boneNode);

                if (singleDirectChild != null)
                {
                    bone.SetFlag(BoneFlags.ToBone);
                    bone.To_Bone = singleDirectChild.Index;
                }
                else
                {
                    // TODO: Fix this; it should point to a world position.
                    bone.To_Offset = transform.Translation.ToOpenTK().FixUnityToOpenTK();
                }

                // No use. This is just a flag to specify more details to rotation/translation limitation.
                //bone.SetFlag(BoneFlags.LocalFrame);
                bone.InitialRotation = transform.Rotation.ToOpenTK().FixUnityToOpenTK();
                bone.CurrentRotation = bone.InitialRotation;

                //bone.Level = boneNode.Level;
                bone.Level = 0;

                if (BoneUtils.IsBoneMovable(boneNode.Path))
                {
                    bone.SetFlag(BoneFlags.Rotation | BoneFlags.Translation);
                }
                else
                {
                    bone.SetFlag(BoneFlags.Rotation);
                }

                if (ConversionConfig.Current.HideUnityGeneratedBones)
                {
                    if (BoneUtils.IsNameGenerated(boneNode.Path))
                    {
                        bone.ClearFlag(BoneFlags.Visible);
                    }
                }

                bones.Add(bone);
            }

            if (ConversionConfig.Current.FixMmdCenterBones)
            {
                // Add master (全ての親) and center (センター), recompute bone hierarchy.
                PmxBone master = new PmxBone(), center = new PmxBone();

                master.Name        = "全ての親";
                master.NameEnglish = "master";
                center.Name        = "センター";
                center.NameEnglish = "center";

                master.ParentIndex = 0; // "" bone
                center.ParentIndex = 1; // "master" bone

                master.CurrentPosition = master.InitialPosition = Vector3.Zero;
                center.CurrentPosition = center.InitialPosition = Vector3.Zero;

                master.SetFlag(BoneFlags.Translation | BoneFlags.Rotation);
                center.SetFlag(BoneFlags.Translation | BoneFlags.Rotation);

                bones.Insert(1, master);
                bones.Insert(2, center);

                //// Fix "MODEL_00" bone

                //do {
                //    var model00 = bones.Find(b => b.Name == "グルーブ");

                //    if (model00 == null) {
                //        throw new ArgumentException("MODEL_00 mapped bone is not found.");
                //    }

                //    model00.ParentIndex = 2; // "center" bone
                //} while (false);

                const int numBonesAdded = 2;

                // Fix vertices and other bones
                foreach (var vertex in vertices)
                {
                    foreach (var boneWeight in vertex.BoneWeights)
                    {
                        if (boneWeight.BoneIndex == 0 && boneWeight.Weight <= 0)
                        {
                            continue;
                        }

                        if (boneWeight.BoneIndex >= 1)
                        {
                            boneWeight.BoneIndex += numBonesAdded;
                        }
                    }
                }

                for (var i = numBonesAdded + 1; i < bones.Count; ++i)
                {
                    var bone = bones[i];

                    bone.ParentIndex += numBonesAdded;

                    if (bone.HasFlag(BoneFlags.ToBone))
                    {
                        bone.To_Bone += numBonesAdded;
                    }
                }
            }

            if (ConversionConfig.Current.AppendIKBones)
            {
                // Add IK bones.

                PmxBone[] CreateLegIK(string leftRightJp, string leftRightEn)
                {
                    var startBoneCount = bones.Count;

                    PmxBone ikParent = new PmxBone(), ikBone = new PmxBone();

                    ikParent.Name        = leftRightJp + "足IK親";
                    ikParent.NameEnglish = "leg IKP_" + leftRightEn;
                    ikBone.Name          = leftRightJp + "足IK";
                    ikBone.NameEnglish   = "leg IK_" + leftRightEn;

                    PmxBone master;

                    do
                    {
                        master = bones.Find(b => b.Name == "全ての親");

                        if (master == null)
                        {
                            throw new ArgumentException("Missing master bone.");
                        }
                    } while (false);

                    ikParent.ParentIndex = bones.IndexOf(master);
                    ikBone.ParentIndex   = startBoneCount; // IKP
                    ikParent.SetFlag(BoneFlags.ToBone);
                    ikBone.SetFlag(BoneFlags.ToBone);
                    ikParent.To_Bone = startBoneCount + 1; // IK
                    ikBone.To_Bone   = -1;

                    PmxBone ankle, knee, leg;

                    do
                    {
                        var ankleName = leftRightJp + "足首";
                        ankle = bones.Find(b => b.Name == ankleName);
                        var kneeName = leftRightJp + "ひざ";
                        knee = bones.Find(b => b.Name == kneeName);
                        var legName = leftRightJp + "足";
                        leg = bones.Find(b => b.Name == legName);

                        if (ankle == null)
                        {
                            throw new ArgumentException("Missing ankle bone.");
                        }

                        if (knee == null)
                        {
                            throw new ArgumentException("Missing knee bone.");
                        }

                        if (leg == null)
                        {
                            throw new ArgumentException("Missing leg bone.");
                        }
                    } while (false);

                    ikBone.CurrentPosition   = ikBone.InitialPosition = ankle.InitialPosition;
                    ikParent.CurrentPosition = ikParent.InitialPosition = new Vector3(ikBone.InitialPosition.X, 0, ikBone.InitialPosition.Z);

                    ikParent.SetFlag(BoneFlags.Translation | BoneFlags.Rotation);
                    ikBone.SetFlag(BoneFlags.Translation | BoneFlags.Rotation | BoneFlags.IK);

                    var ik = new PmxIK();

                    ik.LoopCount       = 10;
                    ik.AngleLimit      = MathHelper.DegreesToRadians(114.5916f);
                    ik.TargetBoneIndex = bones.IndexOf(ankle);

                    var links = new IKLink[2];

                    links[0]            = new IKLink();
                    links[0].BoneIndex  = bones.IndexOf(knee);
                    links[0].IsLimited  = true;
                    links[0].LowerBound = new Vector3(MathHelper.DegreesToRadians(-180), 0, 0);
                    links[0].UpperBound = new Vector3(MathHelper.DegreesToRadians(-0.5f), 0, 0);
                    links[1]            = new IKLink();
                    links[1].BoneIndex  = bones.IndexOf(leg);

                    ik.Links  = links;
                    ikBone.IK = ik;

                    return(new[] {
                        ikParent, ikBone
                    });
                }

                PmxBone[] CreateToeIK(string leftRightJp, string leftRightEn)
                {
                    PmxBone ikParent, ikBone = new PmxBone();

                    do
                    {
                        var parentName = leftRightJp + "足IK";

                        ikParent = bones.Find(b => b.Name == parentName);

                        Debug.Assert(ikParent != null, nameof(ikParent) + " != null");
                    } while (false);

                    ikBone.Name        = leftRightJp + "つま先IK";
                    ikBone.NameEnglish = "toe IK_" + leftRightEn;

                    ikBone.ParentIndex = bones.IndexOf(ikParent);

                    ikBone.SetFlag(BoneFlags.ToBone);
                    ikBone.To_Bone = -1;

                    PmxBone toe, ankle;

                    do
                    {
                        var toeName = leftRightJp + "つま先";
                        toe = bones.Find(b => b.Name == toeName);
                        var ankleName = leftRightJp + "足首";
                        ankle = bones.Find(b => b.Name == ankleName);

                        if (toe == null)
                        {
                            throw new ArgumentException("Missing toe bone.");
                        }

                        if (ankle == null)
                        {
                            throw new ArgumentException("Missing ankle bone.");
                        }
                    } while (false);

                    ikBone.CurrentPosition = ikBone.InitialPosition = toe.InitialPosition;
                    ikBone.SetFlag(BoneFlags.Translation | BoneFlags.Rotation | BoneFlags.IK);

                    var ik = new PmxIK();

                    ik.LoopCount       = 10;
                    ik.AngleLimit      = MathHelper.DegreesToRadians(114.5916f);
                    ik.TargetBoneIndex = bones.IndexOf(toe);

                    var links = new IKLink[1];

                    links[0]           = new IKLink();
                    links[0].BoneIndex = bones.IndexOf(ankle);

                    ik.Links  = links.ToArray();
                    ikBone.IK = ik;

                    return(new[] {
                        ikBone
                    });
                }

                var leftLegIK = CreateLegIK("左", "L");
                bones.AddRange(leftLegIK);
                var rightLegIK = CreateLegIK("右", "R");
                bones.AddRange(rightLegIK);

                var leftToeIK = CreateToeIK("左", "L");
                bones.AddRange(leftToeIK);
                var rightToeIK = CreateToeIK("右", "R");
                bones.AddRange(rightToeIK);
            }

            if (ConversionConfig.Current.AppendEyeBones)
            {
                (int VertexStart1, int VertexCount1, int VertexStart2, int VertexCount2) FindEyesVerticeRange()
                {
                    var meshNameIndex = -1;
                    var cm            = combinedMesh as CompositeMesh;

                    Debug.Assert(cm != null, nameof(cm) + " != null");

                    for (var i = 0; i < cm.Names.Count; i++)
                    {
                        var meshName = cm.Names[i];

                        if (meshName == "eyes")
                        {
                            meshNameIndex = i;
                            break;
                        }
                    }

                    if (meshNameIndex < 0)
                    {
                        throw new ArgumentException("Mesh \"eyes\" is missing.");
                    }

                    var subMeshMaps = cm.ParentMeshIndices.Enumerate().Where(s => s.Value == meshNameIndex).ToArray();

                    Debug.Assert(subMeshMaps.Length == 2, "There should be 2 sub mesh maps.");
                    Debug.Assert(subMeshMaps[1].Index - subMeshMaps[0].Index == 1, "The first sub mesh map should contain one element.");

                    var vertexStart1 = (int)cm.SubMeshes[subMeshMaps[0].Index].FirstVertex;
                    var vertexCount1 = (int)cm.SubMeshes[subMeshMaps[0].Index].VertexCount;
                    var vertexStart2 = (int)cm.SubMeshes[subMeshMaps[1].Index].FirstVertex;
                    var vertexCount2 = (int)cm.SubMeshes[subMeshMaps[1].Index].VertexCount;

                    return(vertexStart1, vertexCount1, vertexStart2, vertexCount2);
                }

                Vector3 GetEyeBonePosition(int vertexStart, int vertexCount)
                {
                    var centerPos = Vector3.Zero;
                    var leftMostPos = new Vector3(float.MinValue, 0, 0);
                    var rightMostPos = new Vector3(float.MaxValue, 0, 0);
                    int leftMostIndex = -1, rightMostIndex = -1;

                    for (var i = vertexStart; i < vertexStart + vertexCount; ++i)
                    {
                        var pos = vertices[i].Position;

                        centerPos += pos;

                        if (pos.X > leftMostPos.X)
                        {
                            leftMostPos   = pos;
                            leftMostIndex = i;
                        }

                        if (pos.X < rightMostPos.X)
                        {
                            rightMostPos   = pos;
                            rightMostIndex = i;
                        }
                    }

                    Debug.Assert(leftMostIndex >= 0, nameof(leftMostIndex) + " >= 0");
                    Debug.Assert(rightMostIndex >= 0, nameof(rightMostIndex) + " >= 0");

                    centerPos = centerPos / vertexCount;

                    // "Eyeball". You got the idea?
                    var leftMostNorm  = vertices[leftMostIndex].Normal;
                    var rightMostNorm = vertices[rightMostIndex].Normal;

                    var   k1 = leftMostNorm.Z / leftMostNorm.X;
                    var   k2 = rightMostNorm.Z / rightMostNorm.X;
                    float x1 = leftMostPos.X, x2 = rightMostPos.X, z1 = leftMostPos.Z, z2 = rightMostPos.Z;

                    var d1 = (z2 - k2 * x2 + k2 * x1 - z1) / (k1 - k2);

                    var x = x1 + d1;
                    var z = z1 + k1 * d1;

                    return(new Vector3(x, centerPos.Y, z));
                }

                Vector3 GetEyesBonePosition(int vertexStart1, int vertexCount1, int vertexStart2, int vertexCount2)
                {
                    var result = new Vector3();

                    for (var i = vertexStart1; i < vertexStart1 + vertexCount1; ++i)
                    {
                        result += vertices[i].Position;
                    }
                    for (var i = vertexStart2; i < vertexStart2 + vertexCount2; ++i)
                    {
                        result += vertices[i].Position;
                    }

                    result = result / (vertexCount1 + vertexCount2);

                    return(new Vector3(0, result.Y + 0.5f, -0.6f));
                }

                var(vs1, vc1, vs2, vc2) = FindEyesVerticeRange();
                PmxBone head;

                do
                {
                    head = bones.Find(b => b.Name == "頭");

                    if (head == null)
                    {
                        throw new ArgumentException("Missing head bone.");
                    }
                } while (false);

                var eyes = new PmxBone();

                eyes.Name        = "両目";
                eyes.NameEnglish = "eyes";

                eyes.Parent      = head;
                eyes.ParentIndex = bones.IndexOf(head);

                eyes.CurrentPosition = eyes.InitialPosition = GetEyesBonePosition(vs1, vc1, vs2, vc2);

                eyes.SetFlag(BoneFlags.Visible | BoneFlags.Rotation | BoneFlags.ToBone);
                eyes.To_Bone = -1;

                bones.Add(eyes);

                PmxBone leftEye = new PmxBone(), rightEye = new PmxBone();

                leftEye.Name         = "左目";
                leftEye.NameEnglish  = "eye_L";
                rightEye.Name        = "右目";
                rightEye.NameEnglish = "eye_R";

                leftEye.Parent       = head;
                leftEye.ParentIndex  = bones.IndexOf(head);
                rightEye.Parent      = head;
                rightEye.ParentIndex = bones.IndexOf(head);

                leftEye.SetFlag(BoneFlags.Visible | BoneFlags.Rotation | BoneFlags.ToBone | BoneFlags.AppendRotation);
                rightEye.SetFlag(BoneFlags.Visible | BoneFlags.Rotation | BoneFlags.ToBone | BoneFlags.AppendRotation);
                leftEye.To_Bone            = -1;
                rightEye.To_Bone           = -1;
                leftEye.AppendParent       = eyes;
                rightEye.AppendParent      = eyes;
                leftEye.AppendParentIndex  = bones.IndexOf(eyes);
                rightEye.AppendParentIndex = bones.IndexOf(eyes);
                leftEye.AppendRatio        = 1;
                rightEye.AppendRatio       = 1;

                leftEye.CurrentPosition  = leftEye.InitialPosition = GetEyeBonePosition(vs1, vc1);
                rightEye.CurrentPosition = rightEye.InitialPosition = GetEyeBonePosition(vs2, vc2);

                bones.Add(leftEye);
                bones.Add(rightEye);

                // Fix vertices
                {
                    var leftEyeIndex  = bones.IndexOf(leftEye);
                    var rightEyeIndex = bones.IndexOf(rightEye);

                    for (var i = vs1; i < vs1 + vc1; ++i)
                    {
                        var skin = vertices[i];
                        // Eyes are only affected by "KUBI/ATAMA" bone by default. So we only need to set one element's values.
                        skin.BoneWeights[0].BoneIndex = leftEyeIndex;
                        Debug.Assert(Math.Abs(skin.BoneWeights[0].Weight - 1) < 0.000001f, "Total weight in the skin of left eye should be 1.");
                    }
                    for (var i = vs2; i < vs2 + vc2; ++i)
                    {
                        var skin = vertices[i];
                        // Eyes are only affected by "KUBI/ATAMA" bone by default. So we only need to set one element's values.
                        skin.BoneWeights[0].BoneIndex = rightEyeIndex;
                        Debug.Assert(Math.Abs(skin.BoneWeights[0].Weight - 1) < 0.000001f, "Total weight in the skin of right eye should be 1.");
                    }
                }
            }

            // Finally, set the indices. The values will be used later.
            for (var i = 0; i < bones.Count; i++)
            {
                bones[i].BoneIndex = i;
            }

            return(bones.ToArray());
        }
示例#31
0
		public static void Insert_JamesBond_Enumerate( IKLink link )
		{
			Console.WriteLine( "\n===== Insert James Bond enumerating the results..." );

			var cmd = link.Insert( x => x.Employees ).Column(
					x => x.Id = "007",
					x => x.FirstName = "James",
					x => x.LastName = "Bond",
					x => x.CountryId = "uk",
					x => x.JoinDate = null,
					x => x.Photo = new byte[] { 0, 0, 7 }
				);
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#32
0
 public IKLink(IKLink link)
 {
     FromIKLink(link);
 }
示例#33
0
		public static void Delete_JamesBond_Enumerate( IKLink link )
		{
			Console.WriteLine( "\n===== Delete James Bond enumerating the results..." );

			var cmd = link.Delete( x => x.Employees )
				.Where( x => x.Id == "007" );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#34
0
		public static void Delete_ManagerNotNull_Enumerate( IKLink link )
		{
			Console.WriteLine( "\n===== Delete the employees whose manager is NOT null enumerating the results..." );

			var cmd = link.Delete( x => x.Employees )
				.Where( x => x.ManagerId != null );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( var obj in cmd ) Console.WriteLine( "\n> Record => {0}", obj );
			cmd.Dispose();
		}
示例#35
0
		public static void Delete_ManagerNotNull_NonQuery( IKLink link )
		{
			Console.WriteLine( "\n===== Delete the employees whose manager is NOT just returning the number..." );

			var cmd = link.Delete( x => x.Employees )
				.Where( x => x.ManagerId != null );
			Console.WriteLine( "\n> Command => {0}", cmd );

			int n = cmd.Execute();
			Console.WriteLine( "\n> Result => {0}", n );

			cmd.Dispose();
		}
示例#36
0
		/// <summary>
		/// Creates a new instance of <see cref="KCommandQuery"/> associating it to the given link.
		/// </summary>
		/// <param name="link">The link this command will be associated to.</param>
		public KCommandQuery( IKLink link ) : base( link )
		{
			DEBUG.IndentLine( "\n-- KCommandQuery( Link )" );

			_TableAliasList = new KTableAliasList( Link.DbCaseSensitiveNames );

			DEBUG.Unindent();
		}
示例#37
0
		public static void Query_Basic_ConversionToType( IKLink link )
		{
			Console.WriteLine( "\n===== Basic Query with conversion to a given type..." );

			var cmd = link.From( x => x.Employees.As( x.Emp ) );
			Console.WriteLine( "\n> Command => {0}", cmd );

			foreach( EmployeeTable obj in cmd.ConvertBy( rec => {
				// Using several ways of accessing the columns...
				EmployeeTable emp = new EmployeeTable(); dynamic d = rec;
				emp.Id = d.Id;
				emp.FirstName = (string)rec["FirstName"];
				emp.LastName = (string)rec["Emp", "LastName"];

				// Using the hard way, the indexed one, we need to take care of the type conversions...
				// object orig = rec["Employees", "BirthDate"];
				// CalendarDate date = orig == null ? null : new CalendarDate( (DateTime)orig );
				// emp.BirthDate = date;

				emp.BirthDate = d.BirthDate; // If using dynamics no conversion specification is needed
				emp.JoinDate = d.JoinDate;
				emp.StartTime = d.StartTime;

				emp.Active = d.Active;
				emp.ManagerId = d.Emp.ManagerId; // Using the alias
				emp.CountryId = d.Employees.CountryId; // Using the table name
				emp.Photo = d.Photo;
				return emp;
			} ) ) Console.WriteLine( "\n> Employee => {0}", obj );

			cmd.Dispose();
		}