Today, Phil, Allen and I worked together on the project in the uni library. It was a great day that we have done many fixes and made the save and load knot to and from a xml file properly. We also made the undo redo working better. The project is now waiting for finalizing. We beleive that we could finish it by Thursday 26th of May.
Big thanks to Phil, Allen and Tim.
Jun
Sunday, May 22, 2011
A string geometry calculation problem has been solved
Hi all,
The suddenly disappeared rope when creating it was found due to a very interesting floating point number calculation issue in computers: the 'NaN', not a number value.
C# defines a valid value called float.NaN for float data type. Under some circumstances, a math calcualtion would get a NaN result,
e.g.,
The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions
The square root of a negative number.
In our project, the calcualtion for the rotation angle, rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, previousAxis)), sometimes returns a NaN as well, this is the root of the problem.
This bug has been fixed by doing---
if (rotationAngle != rotationAngle)
rotationMatrix = Matrix.Identity;
else
rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, rotationAngle);
A new StringGeometry.cs file with the fix will be sent out soon.
Kindest regards,
Jun
The suddenly disappeared rope when creating it was found due to a very interesting floating point number calculation issue in computers: the 'NaN', not a number value.
C# defines a valid value called float.NaN for float data type. Under some circumstances, a math calcualtion would get a NaN result,
e.g.,
The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions
The square root of a negative number.
In our project, the calcualtion for the rotation angle, rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, previousAxis)), sometimes returns a NaN as well, this is the root of the problem.
This bug has been fixed by doing---
if (rotationAngle != rotationAngle)
rotationMatrix = Matrix.Identity;
else
rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, rotationAngle);
A new StringGeometry.cs file with the fix will be sent out soon.
Kindest regards,
Jun
Rotation problem sorted out
Hi Casey,
The rotation problem has been finally solved. Thank you so much for all your help.
Inspired by you, I changed the algorithm for creating the rope a little bit. Instead of always rotating and translating from the base circle to those positions on the central line, now we only do it for the starting circle, but for the rest of circles, each one is based on its previous circle on the central line: rotating and translating from its previous circle. By doing so, we actually avoid the need to handle the complaxity of a lot of different cases. E.g., whenever the rope goes upwards first then goes downwards, or goes forwards first then goes backwards, it has to be ended up with doing:
rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, Vector3.Up));
rotationAngle += MathHelper.Pi;
This is because the Math.Acos returns an angle always smaller than a Pi. But the rope has some cases needing the rotation bigger than Pi, otherwise a crossover (over-rotated ones) would happen, and it's very hard to cover and handle all the cases.
The new algorithm can help avoid this complexity, because the angle between previous cirle base axis and the current circle base axis will never be bigger than a Pi. Hence the problem is solved by doing this:
//get the current circle's base axis
rotationAxis = Vector3.Normalize(calVectors[i + 1] - calVectors[i]);
rotationAxis = Vector3.Normalize(calVectors[i + 1] - calVectors[i]);
//angle between circle's base axis and previous circle's base axis
rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, previousAxis));
rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, previousAxis));
//find a vector perpendicular to both the circle's base axis and the circle's base axis
rotationAxis = Vector3.Cross(rotationAxis, previousAxis);
rotationAxis.Normalize();
rotationAxis = Vector3.Cross(rotationAxis, previousAxis);
rotationAxis.Normalize();
//save current circle's base axis for next run
previousAxis = Vector3.Normalize(calVectors[i + 1] - calVectors[i]);
previousAxis = Vector3.Normalize(calVectors[i + 1] - calVectors[i]);
//construct the rotation matrix from the rotation axis and rotation angle
rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, rotationAngle);
magicMatrix = Matrix.CreateTranslation(-calVectors[i - 1]) * rotationMatrix * Matrix.CreateTranslation(calVectors[i]);
rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, rotationAngle);
magicMatrix = Matrix.CreateTranslation(-calVectors[i - 1]) * rotationMatrix * Matrix.CreateTranslation(calVectors[i]);
newCircle = new Vector3[baseCircle.segPointNo];
//transform from the previous to current one
Vector3.Transform(vectorCircleList[i - 1].vecotrCircle, ref magicMatrix, newCircle);
vectorCircleList.Add(newCircle);
With this new algorithm, we finally got this very nice rope:
Attempting to solve the rotation problem
Hi Casey,
Sorry for my late reply, as I was doing a lot testing on the code, trying to figure the problem out these two days. I found the over-rotation problem is not caused by this code:
else if (rotationAxis == -Vector3.Up)
{
rotationAxis = Vector3.Backward;
rotationAngle = MathHelper.Pi;
}
{
rotationAxis = Vector3.Backward;
rotationAngle = MathHelper.Pi;
}
Now I only use the following code for all cases:
rotationAxis = Vector3.Normalize(calVectors[i + 1] - calVectors[i]);
rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, Vector3.Up));
rotationAxis = Vector3.Cross(rotationAxis, Vector3.Up);
rotationAxis.Normalize();
rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, Vector3.Up));
rotationAxis = Vector3.Cross(rotationAxis, Vector3.Up);
rotationAxis.Normalize();
The problem seems to occur only when the rope goes from up to down. I'm currently looking into the secret of these two lines of code. Maybe I need to add more code to cover all cases:
rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, Vector3.Up));
rotationAxis = Vector3.Cross(rotationAxis, Vector3.Up);
rotationAxis = Vector3.Cross(rotationAxis, Vector3.Up);
Attempting to solve the rotation problem
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/base/pgrs-sm.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
Philip Davies
Jun, that is amazing. Fantastic work! Phil
5/4/2011
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![Offline](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![]() | ![]() | ![]() |
Hi Casey,
Thank you so much! You've been a great help. The code example by you is exactly what we want and it helped resolve the legacy rotation problem in our Knot_A_Problem project from last semester.
Now we can have nicer knot strings: the flat one has gone, and the string can be rotated to any direction in 3D world smoothly. Only, it seems to have been rotated too much in some areas. I'm thinking of the reasons of it. If you know what's wrong there, could you please let me know? The over-rotated ones are shown on the screenshots below:
The code used for it is as following:
rotationAxis = Vector3.Normalize(calVectors[i + 1] - calVectors[i]);
if (rotationAxis == Vector3.Up)
{
rotationAngle = 0f;
}
else if (rotationAxis == -Vector3.Up)
{
rotationAxis = Vector3.Backward;
rotationAngle = MathHelper.Pi;
}
else
{
//angle between circle's base axis and up vector
rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, Vector3.Up));
{
rotationAngle = 0f;
}
else if (rotationAxis == -Vector3.Up)
{
rotationAxis = Vector3.Backward;
rotationAngle = MathHelper.Pi;
}
else
{
//angle between circle's base axis and up vector
rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, Vector3.Up));
//find a vector perpendicular to both the circle's base axis and the up vector, this will be your rotation axis
rotationAxis = Vector3.Cross(rotationAxis, Vector3.Up);
rotationAxis.Normalize();
}
rotationAxis = Vector3.Cross(rotationAxis, Vector3.Up);
rotationAxis.Normalize();
}
//construct the rotation matrix from the rotation axis and rotation angle
Matrix rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, rotationAngle);
Matrix rotationMatrix = Matrix.CreateFromAxisAngle(rotationAxis, rotationAngle);
Matrix magicMatrix = rotationMatrix * Matrix.CreateTranslation(calVectors[i]);
Vector3[] newCircle = new Vector3[baseCircle.segPointNo];
Vector3.Transform(baseCircle.vecotrCircle, ref magicMatrix, newCircle);
Vector3.Transform(baseCircle.vecotrCircle, ref magicMatrix, newCircle);
Do you think it's the Gimbal lock issue or do we need to make more check on the 'rotationAngle = -(float)Math.Acos(Vector3.Dot(rotationAxis, Vector3.Up));' ?
Kind regards,
Jun
From: Casey Chow [caseyc@uow.edu.au]
Sent: Thursday, April 28, 2011 6:22 AM
To: Jun Ye
Cc: Luke McAven; philip_m_davies@hotmail.com; timothy overton [timothy_overton@hotmail.com]; Xun He; jernej.cesar@gmail.com
Subject: RE: Rotation Issue - CSCI321 - From Jun
Sent: Thursday, April 28, 2011 6:22 AM
To: Jun Ye
Cc: Luke McAven; philip_m_davies@hotmail.com; timothy overton [timothy_overton@hotmail.com]; Xun He; jernej.cesar@gmail.com
Subject: RE: Rotation Issue - CSCI321 - From Jun
Hi Jun,
Following my previous email, depending on what you are trying to do, I don't think Euler angles is what you need. If I understand correctly, for your purposes what you can do is to construct the rotation matrix from an axis and an angle. I've hacked up some XNA code (attached) that shows you how to do this, you should be able to figure it out from there.
Regards,
Casey
In response to the message from Jun Ye, 4/23/2011
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/base/pgrs-sm.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
Casey Chow
Hi Jun, Following my previous email, depending on what you are trying to do, I don't think Euler angles is what you need. If I understand correctly, for your purposes what you can do is to construct the rotation matrix from an axis and an angle. I've hacked
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
4/28/2011
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![Offline](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
Thursday, April 28, 2011 6:22 AM
![]() | ![]() | ![]() |
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
Hi Jun,
Following my previous email, depending on what you are trying to do, I don't think Euler angles is what you need. If I understand correctly, for your purposes what you can do is to construct the rotation matrix from an axis and an angle. I've hacked up some XNA code (attached) that shows you how to do this, you should be able to figure it out from there.
Regards,
Casey
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/base/pgrs-sm.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
Casey Chow
Hi Jun, Apologies for the late reply. I think you've got the wrong idea about Euler angles, matrices and quaternions. Whether or not you use Euler angles or quaternions, you still perform transformations using matrices (in XNA Matrix.CreateFromQuaternion(quaternion);
4/27/2011
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![Offline](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![Offline](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![Offline](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![Offline](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![Offline](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
![Offline](https://r3.res.outlook.com/owa/14.1.225.52/themes/resources/clear1x1.gif)
Wednesday, April 27, 2011 7:45 PM
![]() | ![]() | ![]() |
Hi Jun,
Apologies for the late reply.
I think you've got the wrong idea about Euler angles, matrices and quaternions. Whether or not you use Euler angles or quaternions, you still perform transformations using matrices (in XNA Matrix.CreateFromQuaternion(quaternion); )
However, if I understand you correctly, what you're asking instead (from "The problem is how we could calculate the Euler angle... ") is how to calculate the Euler angles from Vector.Up to the rotated vector?
If so, you can do this by calculating the projection of the rotated vector onto the xz, yz, and xy planes, then finding the individual angles between the projected vectors and the x, y, and z reference vectors respectively.
Regards,
Casey
Attempting to solve the rotation problem
Hi Casey,
I'm still working on resolving the rotation problem, but haven't been able to get a correct yaw, pitch and roll.
If I understood Matrix and Quaternion correctly, they can both be used to do rotations. In the case of rotation, Matrix could possibly have the Gimbal lock issue, but Quaternion is partiqularly designed to avoid this problem and Quaternion has better performance on intensive rotation calculation.
As illustrated below, suppose I have two normalized Vector3 representing two directions, how can I get the correct values of yaw, pitch and roll from the difference between this two directions:
I'm still working on resolving the rotation problem, but haven't been able to get a correct yaw, pitch and roll.
If I understood Matrix and Quaternion correctly, they can both be used to do rotations. In the case of rotation, Matrix could possibly have the Gimbal lock issue, but Quaternion is partiqularly designed to avoid this problem and Quaternion has better performance on intensive rotation calculation.
As illustrated below, suppose I have two normalized Vector3 representing two directions, how can I get the correct values of yaw, pitch and roll from the difference between this two directions:
Cheers,
Jun
Attempting to solve the rotation problem
For now, I'd like to jsut post couples of my emails as my diaries:
Hi Casey,
How are you? This is Jun once doing CSCI336 and 356 under you. Haven't seen you around Wollongong campus for a long time, I'm wondering that you are probably in Singapore at the moment.
I'm currently doing CSCI321 project and this is my last semester in my bachelor degree. A group of us are doing a software project called Knot under Luke. The software is to allow users to create and learn how to tie some knots, like this:
We are currently facing a difficulty and although tried many methods many times, we cannot solve it properly. Could you do us a favor and help?
The problem is as bellow:
We use a set of base points (a cycle in the 0 position of the world) as the reference. We calculate a central line (a cubic curve calcuated using a set of control points). Then for each point we pick up on the central line, we try to use Matrix.CreateTranslation and Matrix.CreateRotation to copy, move and rotate the base cycle to get the surface points we want on the cube. The following code is what we are using. It seems only the translation is working:
Matrix magicMatrix = Matrix.CreateTranslation(calVectors[i]); // calVectors[i] is a point on the central line
Vector3[] newCycle = new Vector3[cyclePointNumber]; // cyclePointNumber is the number of points we take from the base cycle
Vector3.Transform(baseCircle, ref magicMatrix, newCycle); // baseCircle is Vector3[]
Vector3[] newCycle = new Vector3[cyclePointNumber]; // cyclePointNumber is the number of points we take from the base cycle
Vector3.Transform(baseCircle, ref magicMatrix, newCycle); // baseCircle is Vector3[]
By doing so, we get some unwanted cube geometries --- when the geometry goes horixontally, it becomes flat, as shown on the image bellow:
To solve this problem, we tried something like:
Vector3 currentCircleDirection = calVectors[i+1] - calVectors[i];
currentCircleDirection.Normalize(); // get the current direction of the current point on the central line
currentCircleDirection.Normalize(); // get the current direction of the current point on the central line
Matrix magicMatrix = Matrix.CreateTranslation(calVectors[i]); // move to new position
After translation, how can I use the currentCircleDirection to rotate the circle properly? Using Matrix.CreateRotationX, or Y, or Z? Or do something like magicMatrix.Forward = currentCircleDirection?
We tried many formulars and tests, but all failed. How can I use the currentCircleDirection to not only make the magicMatrix have the right info of the new position, but also have the right direction (rotation)?
Thanks very much for your time Casey!
Warm regards,
Jun
Saturday, March 26, 2011
Working on editing diagrams and class documentation
This week, I put my energy on editing the class diagrams and class documentation according to these new changes on the rendering engine side in the past couple of weeks.
Class documentation has been revised as well. A xml formater will later help produce nice looking docs on the design of the rendering engine part.
Class documentation has been revised as well. A xml formater will later help produce nice looking docs on the design of the rendering engine part.
Some fixes on the rendering engine and it's almost the finalized version of the engine
Some updates and fixes on the engine:
1. The engine is now running by default on fullscreen, it's now able to fetch user's machine resolution and configure to fit this resolution to get a best looking of the interface and rendering area.
2. I have made changes on the editing word coordinator axes. It's now much elegant than before, which has got a cone head and thinner sticks, making it easy to select as well.
3. The first two editing ball will be shown to indicate that the user has successfully add the first two control points.
1. The engine is now running by default on fullscreen, it's now able to fetch user's machine resolution and configure to fit this resolution to get a best looking of the interface and rendering area.
2. I have made changes on the editing word coordinator axes. It's now much elegant than before, which has got a cone head and thinner sticks, making it easy to select as well.
3. The first two editing ball will be shown to indicate that the user has successfully add the first two control points.
Working on updating the rendering engine and communicating with other group members
I think this email sending to all group members would be diary to show what I'm doing this week ---
Hi all,
While I'm working on updating the rendering engine and doing some fixes on it, some important things to say again.
1) Please forgive me to say it again: each of us should at least post 6 diaries by week 6.
2) I will upload the "almost finalized" version of our rendering engine tomorrow. The engine will by default run at fullscreen mode, as Luke wants, it will be smart enough to know users' machine resolution and configure to fit it. If user presses Alt + Enter key, the engine switchs back to 1280 * 800, a classic safe resolution that fits most of machines.
3) The rendering engine now will show a control point ball for first two points to let users know they have successfully add the first two points before we render a knot string starting from third point.
4) Jernej, the size of the button bar for you is determined to be 180 * 800.
5) Phil, the updated engine has been implemented with the XML and database code. Besides this, I have made examples for you to insert button related code so that you do not have to worry about those hard things, such as the alpha blending & rendering state. My intention is to save your time and make things easier for all of others. All code between the comments, // for buttons & // end of buttons, is the implemented button related code. The button framework I used is from a famous xna tutorial: http://alecjacobson.com/games/button-tutorial/ http://www.alecjacobson.com/weblog/?p=539 . This button framework has implemented the Up, Over & Click event handling and color changing. Not only that, it has a very nice advantage that it can recognise if your mouse is over or click the irregular textured area and left other transparent area static. This will be very nice feature for you to draw buttons on the top of Jernej's rope-wood ladder. Hope you will like it.
6) I don't think we need to draw a menu like button bar at the top of the rendering area. As talked to Luke, we only need to draw the essential & important buttons on the right hand side. For those minor operation and short keys, we could simple document it in the user manual.
7) So, what is the next most important thing? We need to look into Jernej's work, check to see how many buttons we could have. We need to make the decision: if we only draw 15 buttons, then which buttons are at this high priority. To work it out, I appeal, each of us, while you are testing and playing around with the rendering engine, please list 15 buttons that you think need to put on the button bar. Please send it back to Tim and CC to other group members by Thursday. So that we can disccuss and make final decision with Luke in Thursday meeting.
Kind regards,
Jun
Hi all,
While I'm working on updating the rendering engine and doing some fixes on it, some important things to say again.
1) Please forgive me to say it again: each of us should at least post 6 diaries by week 6.
2) I will upload the "almost finalized" version of our rendering engine tomorrow. The engine will by default run at fullscreen mode, as Luke wants, it will be smart enough to know users' machine resolution and configure to fit it. If user presses Alt + Enter key, the engine switchs back to 1280 * 800, a classic safe resolution that fits most of machines.
3) The rendering engine now will show a control point ball for first two points to let users know they have successfully add the first two points before we render a knot string starting from third point.
4) Jernej, the size of the button bar for you is determined to be 180 * 800.
5) Phil, the updated engine has been implemented with the XML and database code. Besides this, I have made examples for you to insert button related code so that you do not have to worry about those hard things, such as the alpha blending & rendering state. My intention is to save your time and make things easier for all of others. All code between the comments, // for buttons & // end of buttons, is the implemented button related code. The button framework I used is from a famous xna tutorial: http://alecjacobson.com/games/button-tutorial/ http://www.alecjacobson.com/weblog/?p=539 . This button framework has implemented the Up, Over & Click event handling and color changing. Not only that, it has a very nice advantage that it can recognise if your mouse is over or click the irregular textured area and left other transparent area static. This will be very nice feature for you to draw buttons on the top of Jernej's rope-wood ladder. Hope you will like it.
6) I don't think we need to draw a menu like button bar at the top of the rendering area. As talked to Luke, we only need to draw the essential & important buttons on the right hand side. For those minor operation and short keys, we could simple document it in the user manual.
7) So, what is the next most important thing? We need to look into Jernej's work, check to see how many buttons we could have. We need to make the decision: if we only draw 15 buttons, then which buttons are at this high priority. To work it out, I appeal, each of us, while you are testing and playing around with the rendering engine, please list 15 buttons that you think need to put on the button bar. Please send it back to Tim and CC to other group members by Thursday. So that we can disccuss and make final decision with Luke in Thursday meeting.
Kind regards,
Jun
Friday, March 18, 2011
More mouse event handling
Today, I was working on adding more mouse event handling to the rendering
engine, so that the operations using mouse can be much more elegant. Left
click remains the same to do add pints, slecet a control point, and all other
basic operations as usual. The middle mouse wheel scroll is to move a camera
(zoom in or zoom out). Its drag & drop is now being used to move camera to
four directions, Up, Down, Left, and Right, which is same as the operations
using Up, Down, Left and Right arrow key. The right mouse button drag & drop
is now used to rotate the knot objects in the scence.
engine, so that the operations using mouse can be much more elegant. Left
click remains the same to do add pints, slecet a control point, and all other
basic operations as usual. The middle mouse wheel scroll is to move a camera
(zoom in or zoom out). Its drag & drop is now being used to move camera to
four directions, Up, Down, Left, and Right, which is same as the operations
using Up, Down, Left and Right arrow key. The right mouse button drag & drop
is now used to rotate the knot objects in the scence.
User interface testing
To test if our rendering engine is robust enough and check to see what kind of
user interface is good to create, this week I'm working on testing a user
interface. I decided to draw buttons on the right hand side as it looks nice
and needs less changes on the engine code. Each view has now got a text to
indicate which view it is. I think we should have a status bar at the bottom
of the knot rendering area. Three buttons are drawn for the testing: Select,
Add points, and Delete.
user interface is good to create, this week I'm working on testing a user
interface. I decided to draw buttons on the right hand side as it looks nice
and needs less changes on the engine code. Each view has now got a text to
indicate which view it is. I think we should have a status bar at the bottom
of the knot rendering area. Three buttons are drawn for the testing: Select,
Add points, and Delete.
Database stuff and XML
Today I worked with Allen to add the abilities to our rendering engine to
allow saving snapshots to a local xml file and uploading snapshots to an
online database server. Allen's own framework in web programming is impresive.
It has made my life easier. Simply add the compiled framework dll files,
create PointModel, StepModel, LineModel, and KnotModel, corresponding to the
control point, a snapshot, a string, and a knot in the rendering engine. It
can then easily serialize the data to be xml form and database stuff, then
save it, upload it. The deserialization, as well, very easy and nice to use.
Currently, press L key is to save the snapshots and K key is to load a set of
knot snaphots in run time.
allow saving snapshots to a local xml file and uploading snapshots to an
online database server. Allen's own framework in web programming is impresive.
It has made my life easier. Simply add the compiled framework dll files,
create PointModel, StepModel, LineModel, and KnotModel, corresponding to the
control point, a snapshot, a string, and a knot in the rendering engine. It
can then easily serialize the data to be xml form and database stuff, then
save it, upload it. The deserialization, as well, very easy and nice to use.
Currently, press L key is to save the snapshots and K key is to load a set of
knot snaphots in run time.
Texture changing & Snapshot traversal
In yesterday's meeting, Luke wanted us to improve the 3D knot rendering
engine, mainly two things: 1. to allow user to change the texture of the
strings; 2. when in the snapshot mode, an user should not only be able to play
the animation to see how a knot is tied, but also be able to walk through each
snapshot one by one forwardly and backwardly. 4.5 hours of work today, I have
implemented these two functionalites on the engine.
engine, mainly two things: 1. to allow user to change the texture of the
strings; 2. when in the snapshot mode, an user should not only be able to play
the animation to see how a knot is tied, but also be able to walk through each
snapshot one by one forwardly and backwardly. 4.5 hours of work today, I have
implemented these two functionalites on the engine.
Subscribe to:
Posts (Atom)