Archive

Posts Tagged ‘open’

A Scalable Solution Part Two: World Reference Frame

In part one of this series, I talked about scaling objects in the local reference frame and why that process is relatively simple. In this post, I will be introducing scaling in the world reference frame as well as detailing some of the differences between the two types of scaling. I will also be detailing some of the complexities as well as a possible implementation.

World reference frame scaling is somewhat more complex when compared to scaling in the local reference frame. As the name implies, this method scales an object against the world reference frame. This is not as simple as it sounds as there are some subtle complexities.

As an operation, scaling in the world reference frame is lossy if other operations such as move and rotate are performed between the scale operations. This is somewhat similar to rotating an object in 3D. In 3D rotation, rotating an object about a set of axes in some order produces a certain result where changing that order would change the final result. When scaling against the world reference frame, one needs to keep in mind that the object may rotate or scale imbetween operations while the world reference frame remains fixed. When scaling groups of objects against the world reference frame, it is also expected that the difference between their positions and the position of the centroid of the group will also scale in the same way as the objects themselves. This does not map very well to the independent transform controls typically offered by most 3D engines today; instead, we will most likely have to create and maintain our own transformation matrix, feeding that to the rendering engine on render time.

We would like to allow the user to scale an object or groups of objects in local and in world reference frames. A relatively simple way to implement this is by storing all transformations in a single transformation matrix. To retrieve the axes for scaling in local reference frame, the transformation matrix is decomposed and the rotation component is used to compute the three axial vectors. In world reference frame, decomposition is not required as the axial vectors are simply the unit vectors of the world’s reference frame ([1,0,0], [0,1,0], [0,0,1] respectively). In either case, the scale is applied by calculating a scale matrix from the axial vectors and some specified scale amount. The scale matrix is then applied to the current transform matrix thereby giving us the object’s new transformation matrix.

This is how an object is scaled in the world reference frame.

This implementation requires that scale and rotation be stored as a combined transform matrix. A side-effect is that scaling in the world reference frame may change rotation. I was against this idea initially as it felt like the “purity” of independent scale and rotation values is being lost, not to mention the performance hit of the frequent matrix compositions and decompositions. Having said that, I don’t think that there is another way for this to be done. Not to mention that scaling in the world reference frame against an arbitrarily rotated object is essentially a skew operation. Comments from more experienced hands on this subject would certainly be appreciated.

Advertisements

A Scalable Solution Part One: Local Reference Frame

May 10, 2012 1 comment

Blog Reading Requirement: you need to know what a reference frame is, from wiki:

“A frame of reference in physics, may refer to a coordinate system or set of axes within which to measure the position, orientation, and other properties of objects in it, or it may refer to an observational reference frame tied to the state of motion of an observer. It may also refer to both an observational reference frame and an attached coordinate system as a unit…”

Read the source article here.

In this series of blog posts, I will be talking about scaling 3D objects in their local reference frame and in the world reference frame. In part one, I will be introducing the topic and detailing scaling in the local reference frame. In part two, I will be introducing scaling in the world reference frame as well as detailing some of the differences between the two types of scaling. I will also be detailing some of the complexities as well as a possible implementation.

As an artist, the ability to scale groups of objects is fairly important when working with 3D models. When scaling an object, it is done against a known axial reference frame; typically, the two most useful reference frames are the world reference frame and the local reference frame and they are vastly different. The local reference frame changes as the object is rotated while the world reference frame never changes. I will take this blog to elaborate on some of the challenges and requirements involved in implementing these manipulations as well as giving a possible implementation.

Local reference frame scaling is the simpler of the two as it is performed against the local reference frame of the object that is being scaled. With groups of objects, it is expected that each object in the group is scaled against its own local reference frame as opposed to the reference frame of the group. It is also expected that the positions of the objects in the group will not be affected by the scaling operation.

This scaling method is simple because it only involves applying a scaling transform against the 3 known axes of any given object. This means that the scale parameters can be stored as 3 floats. During frame rendering, the transform could be applied after position and rotation have been applied; this fits in with the rendering pipeline of most 3D engines and means that one could simply alter the scale parameter present on a renderable object in most 3D engines.

In part two, I will be introducing world reference frame scaling and what complexities may arise from allowing the combination of the two methods. Thank you for reading.

Release 0.4 – Not so much a bang but a whisper

December 13, 2011 Leave a comment

Here we are at the bottom end of OSD600. This course has been fun and has taught me a lot. This is why it is all the more unfortunate that my 0.4 release is not nearly as atomic as my 0.3. For my 0.4, I had 2 projects to work on alongside another course. One project was migrating XSS Me from the current tab-based threadpool implementation to Web Workers. This didn’t go so well. The conclusion of my research into Web Workers deemed them unusable for XSS Me’s requirements. So instead, a very minor fixup was in order.

As for Paladin, as usual, quite a lot of work went into the configurator. The configurator is now closer than ever to landing but still has not landed. This iteration, quite a number of changes went into the configurator. I’ve itemized the changes below:

  • Store/load now accept named parameters
  • Configurator objects were receiving undefined guids, now test suite fails if that happens
  • ConfNode is now it’s own require module
  • Configurator constructor is now not stored on engine
  • Configurator attempts to test for db caps on engine startup
  • Logger is now accepted as a construction option
  • Configurator now picks up default.js
  • /gladius/gameID is now just /id
  • Error handlers now introduced to indexeddb function hierarchy
  • Try/catch around sensitive areas

I will continue to work on XSS Me and paladin.

Release Details:

XSS Me:

commit: 731fe1563f97ab3951a5c799257a9acaea945cd3

issue thread: https://github.com/SecurityCompass/XSSMe/issues/3

pull request: https://github.com/SecurityCompass/XSSMe/pull/4

Paladin:

commit: 4539a66ee3a5ac6a38c420c089781f66e4120eb7

issue thread: https://github.com/alankligman/gladius/issues/21

pull request: https://github.com/alankligman/gladius/pull/52

Done and Done, Pt. 2

November 13, 2011 5 comments

Success! I’ve managed to alter the reported location of the cursor! Here’s what I did to get it to work:

The file that I had to modify was content/events/src/nsDOMMouseEvent.cpp, this is the implementation file of the DOM MouseEvent in firefox.
The updates were as follows:

// ... snip ... line 223

NS_METHOD nsDOMMouseEvent::GetScreenX(PRInt32* aScreenX)
{
  NS_ENSURE_ARG_POINTER(aScreenX);
  //*aScreenX = GetScreenPoint().x;
  *aScreenX = 17000;
  return NS_OK;
}

NS_IMETHODIMP
nsDOMMouseEvent::GetScreenY(PRInt32* aScreenY)
{
  NS_ENSURE_ARG_POINTER(aScreenY);
  //*aScreenY = GetScreenPoint().y;
  *aScreenY = 18000;
  return NS_OK;
}

NS_METHOD nsDOMMouseEvent::GetClientX(PRInt32* aClientX)
{
  NS_ENSURE_ARG_POINTER(aClientX);
  //*aClientX = GetClientPoint().x;
  *aClientX = 7000;
  return NS_OK;
}

NS_IMETHODIMP
nsDOMMouseEvent::GetClientY(PRInt32* aClientY)
{
  NS_ENSURE_ARG_POINTER(aClientY);
  //*aClientY = GetClientPoint().y;
  *aClientY = 8000;
  return NS_OK;
}

// ... /snip ...

As you can see, I forced the reported values for the cursor’s position to be 17000/18000 for the screenX/screenY members and 7000/8000 for the clientX/clientY members. This is a pretty naive way to do it but it proved to produce results. Check it out!

This is what happens now when a user attempts to right click anywhere in the page. As you can see, the context menu appears far off into the right bottom corner ( since the coordinates go off screen ).

Interestingly enough, the changes to the event class do not affect the native windows right click context menu ( can be triggered by right clicking in the same vertical space as the minimize/maximize/close buttons ), as can be seen here. Also not affected is text selection and clicking buttons/links and forms.

Also interesting is that no assertion errors are usually thrown. I have managed to provoke an assertion error however simply by middle clicking ( click the wheel of your mouse if you have a mouse wheel ) somewhere inside the page; the page being used should have sufficient text for the quick drag middle click popup to appear, for an example this page should work. Scroll around a bit if you don’t first succeed.

In conclusion, it seems that it is not immediately obvious how MouseEvent is used internally. On the one hand, the values reported through the event to the js engine are the only way for the js to figure out where the cursor is; so as far as the js is concerned, whatever we return here will be where the js believes the cursor to be. On the other hand, some internals seem to use the values returned from the getter functions of the mouse event object as well; this may make updating the values to our whims possibly difficult due to the sheer size of firefox’s internals and the fact that we don’t *exactly* know what will be affected by our meddling.


P.S. The MouseEvent class also defines some longs (screenX, screenY, clientX, clientY); from what I could tell, these are only updated during initialization:

// ... snip ... line 106

NS_IMETHODIMP
nsDOMMouseEvent::InitMouseEvent(const nsAString & aType, PRBool aCanBubble, PRBool aCancelable,
                                nsIDOMAbstractView *aView, PRInt32 aDetail, PRInt32 aScreenX, 
                                PRInt32 aScreenY, PRInt32 aClientX, PRInt32 aClientY, 
                                PRBool aCtrlKey, PRBool aAltKey, PRBool aShiftKey, 
                                PRBool aMetaKey, PRUint16 aButton, nsIDOMEventTarget *aRelatedTarget)
{
  nsresult rv = nsDOMUIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
  NS_ENSURE_SUCCESS(rv, rv);

  switch(mEvent->eventStructType)
  {
    case NS_MOUSE_EVENT:
    case NS_MOUSE_SCROLL_EVENT:
    case NS_DRAG_EVENT:
    case NS_SIMPLE_GESTURE_EVENT:
    case NS_MOZTOUCH_EVENT:
    {
       static_cast(mEvent)->relatedTarget = aRelatedTarget;
       static_cast(mEvent)->button = aButton;
       nsInputEvent* inputEvent = static_cast(mEvent);
       inputEvent->isControl = aCtrlKey;
       inputEvent->isAlt = aAltKey;
       inputEvent->isShift = aShiftKey;
       inputEvent->isMeta = aMetaKey;
       mClientPoint.x = aClientX;
       mClientPoint.y = aClientY;
       inputEvent->refPoint.x = aScreenX;
       inputEvent->refPoint.y = aScreenY;

       if (mEvent->eventStructType == NS_MOUSE_EVENT) {
         nsMouseEvent* mouseEvent = static_cast(mEvent);
         mouseEvent->clickCount = aDetail;
       }
       break;
    }
    default:
       break;
  }

  return NS_OK;
} 

// ... /snip ...

It may also be interesting to play around with these values; I have not touched these values for this update.

My First Pull Request

October 1, 2011 Leave a comment

Just now, I’ve submitted my first github pull request for the Mozilla/Paladin initiative and already I made some mistakes! The workflow to submitting a pull request is clearly outlined in their workflow page (which I read ages ago and forgot about entirely :P).

Luckily, things are mostly OK but I should have done some make tests before throwing my branch into the fray. I am currently performing those tests post-request submit…

Next time, hopefully the order of things will have improved 🙂

Configuration Registry, Rel 0.1

September 29, 2011 Leave a comment

For the past little while, I’ve been working on a particular issue in Paladin’s issue tracking system. That issue proposes the creation of a configuration registry subsystem that will someday determine which Gladius subsystems execute and with which options.

At the moment, setting configuration options in Gladius is a bit of a mixed bag; this new subsystem should improve the state of things.

Tonight is my first milestone in the creation of this subsystem. I’ve written my ideas on how the subsystem will be designed and will operate, ( https://github.com/northWind87/gladius/wiki/Issue-21—Configurator-Registry-Design )
and I’ve also written the bulk of the unit tests that will tell us when the subsystem is more or less ready for primetime ( https://github.com/northWind87/gladius/blob/develop_issue_21/test/core/Configurator.js ).

Guys, humph, take a look and tell me what you think. I’d very much like someone to tell me in which specific ways my tests are terrible, I think that I would appreciate that a lot 🙂

I’ve always liked the TDD approach (http://en.wikipedia.org/wiki/Test-driven_development ) and hopefully the many scanning eyes of the internet can tell me where I can improve!

Cheers guys and good luck with all of your 0.1 releases!

Get ready to restart firefox…

September 25, 2011 2 comments

Trying to step along paladin’s unit test suite to get a handle on how the engine operates inside of firebug. Things are working out pretty alright when I don’t make the mistake of stepping into the line after the last line in the script because then… firefox crashes 😦

So far I’ve restarted firefox 3 times in the last ten minutes, I’m sure I’ll discover a workaround soon or just learn not to be stupid; anyone else have any similar experiences?