bugs on mantis: who assigns them ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
26 messages Options
12
Reply | Threaded
Open this post in threaded view
|

bugs on mantis: who assigns them ?

Dan Corneanu
Hi,
how do bugs on mantis get assigned to someone? Who is responsible
for this?

Reply | Threaded
Open this post in threaded view
|

Re: bugs on mantis: who assigns them ?

Ken Causey-3
YOU DO!!! :)

When you report a bug and assign it a category (which I hope you and
everyone else will do, otherwise I have to) that assigns the bug to a
team.  Currently there is not a team for every category, not even close,
nonetheless as these teams are formed they will pick up the categories
and since you have already assigned them they will have their bugs
assigned to them all in one step.

Ken Causey

On Tue, 2006-03-07 at 18:39 +0200, Dan Corneanu wrote:
> Hi,
> how do bugs on mantis get assigned to someone? Who is responsible
> for this?




signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Ask not what the board can do for you, ask rather what you can do for us all (was: Re: bugs on mantis: who assigns them ?)

timrowledge
On the subject of Mantis and who does what with it:

It's great when someone takes the time to report a problem and still  
better when they include a decent amount of information about the  
problem, how it happened, what image, what machine, what VM, update  
level etc. Reading  http://www.chiark.greenend.org.uk/~sgtatham/ 
bugs.html is a useful way to spend a moment.

What happens next is..... nothing much, usually. This is a tragedy.  
All that information waiting to be used to improve our world. Sigh.

So what are you going to do about it? Yes *you*, stop squirming and  
sit up straight, pay attention and resolve to take your part properly  
in this process. The simple fact is that for complex problems there  
are only a few people with the experience to have much likelihood of  
success and most of them are very busy. Anything that can be done to  
save time will improve the chance of a complex problem getting  
tackled and *that* can be done by almost any of us. In the process of  
the simple jobs I am about to suggest we are going to learn and  
eventually become expert enough to tackle bigger works, maybe.

Job 1: making sure the report makes sense
Just about anyone (even me on a monday morning pre-caffeine) can  
check a random report, see if it has even faintly enough information  
to mean anything and decide if it has a hope of being useful. If data  
is lacking, try contacting the original reporter to see if they can  
offer more grist for the mill. If they can't, or won't, or say they  
can reproduce it then we can only sensibly close the report. If you  
can find related seeming reports using the mantis search facility,  
link them together.

Job 2: making sure it's reproducible
Just about anyone (blah blah) can try to reproduce a problem. If  
there seems to insufficient information to be able to, see Job 1.  
Assuming you can reproduce the problem you can add your experience to  
the report. If it took some time to get to the problem, consider  
saving an image/changes/ script for future reference.

Job 3: assign it to someone plausible
A lot of the time it is quickly obvious where the problem lies and  
you can assign the report to the right people. If you don't know the  
right assignee, change the report status to feedback and assign it to  
your best guess.  It's not like you're ordering the person to do work.
What we could do with in the Mantis setup is a more useful list of  
assignable names; I'd really prefer to see 'VM guys', 'Collections  
folks', 'Windows weenie' than 'fred', 'jkr' etc. Roles are better  
than names for this purpose.

The nice thing is that you don't have to do all three of these. If  
you are a real newcomer with an urge to help, just do a bunch of Job  
1. If you can achieve a report that makes sense to you as a newcomer  
then it ought to be really clear to someone more experienced. If you  
can't make time to test stuff but know a good bit about what goes  
where and who deals with it, do a bunch of Job 3.

Right now there's only 289 reports listed on the Squeak mantis board.  
If everyone that was eligible to vote in the recent board elections  
(340-something?) took a look at doing one of the above jobs per day -  
forget about actually working on the bug in detail - then within a  
week we could have every report checked on by several sets of eyes.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: LC: Lobotomize CPU



Reply | Threaded
Open this post in threaded view
|

Re: Ask not what the board can do for you, ask rather what you can do for us all (was: Re: bugs on mantis: who assigns them ?)

Marcus Denker

On 07.03.2006, at 19:55, tim Rowledge wrote:

> On the subject of Mantis and who does what with it:
>
> It's great when someone takes the time to report a problem and  
> still better when they include a decent amount of information about  
> the problem, how it happened, what image, what machine, what VM,  
> update level etc. Reading  http://www.chiark.greenend.org.uk/ 
> ~sgtatham/bugs.html is a useful way to spend a moment.
>
> What happens next is..... nothing much, usually. This is a tragedy.  
> All that information waiting to be used to improve our world. Sigh.
>

What I would like to try once would be managing those issues on  
mantis "GTD" style... I suppose everyone on this list knows what GTD  
is... no?
So there are those kinds of books that nobody admits of reading but  
magically they sell a lot: Self Help Books. (I hear a terrified  
scream from the back).
GTD is just one of those books... but it was somwhow good enough to  
get it's own TLA. Now that says something about hacker-compatibility...

The first step to GTD is to take the amorphous blob (Mantis) and  
declare it to be the INBOX. Now let's take every item out of the  
INBOX and ask
one simple Question: "What is the next action?".... and so on. There  
are lots of descriptions of the process on the web (just google for  
GTD to learn more).

It would be interesting to see how this process would work out... the  
main problem with most items in Mantis is that we exactly have not  
defined
what need to happen next. Does it need to be discussed? Routed to a  
Team? put into 3.9a? or 3.8? or both? patched to be able to be added  
to 3.9a?

Hard to say with the current setup. And then all the stuff that I  
can't do anything about, why do I see that? For me, a Graphics bug is  
done as soon as
I have recognized it to be a graphics bugs. i can't do anything. move  
along. Same with network, VM, lots of stuff. There are thigs where  
the issue
needs to be discussed. Others are Projects, we know that they should  
be done, but it will take a huge effort: for bugfixing, there is  
nothing that
can be done. Then there is the general difference between "bugs that  
need to be fixed" and "bugs that are fixed but the fix is not yet in  
the release".
Other issues have a huge discussion, mayeb 5 different changesets,  
some containing tests, some different versions of a fix. What is the  
next action?

It would be nice to filter a true "next actions" list out of that big  
pile of stuff  that we have now on mantis.

Maybe we can start simple: Define "Next action" for each and every  
bug report, just as a comment. That would be a start.

     Marcus

Reply | Threaded
Open this post in threaded view
|

Re: bugs on mantis: who assigns them ?

Alan Grimes
In reply to this post by Ken Causey-3
Here's what I do when I find a bug in squeak:

1. 90% of the time fix it myself without telling anyone, the rest I
can't fix and I try to report...

2. I play around with squeak's built-in reporting system and get yelled
at to post it on Mantis instead...

3. Scratch my head and wonder what a carnivorous insect has to do with
my bug...

4. Wait 4 days...

5. In the middle of a dream, while my mind is making random
associations, that mantis is actually squeak's bug tracking system.

6. go to one of the well known squeak sites such as squeak.org looking
for a convenient link to the site. -- which fails...

7. google the damn thing yet again... (except that I'm beyond caring at
this point...)


--
Don't let your schoolwork get in the way of your learning.

http://users.rcn.com/alangrimes/

Reply | Threaded
Open this post in threaded view
|

Re: bugs on mantis: who assigns them ?

Göran Krampe
Alan Grimes <[hidden email]> wrote:
> Here's what I do when I find a bug in squeak:
[SNIP of blablabla]

You forgot:

8. Bitch on squeak-dev instead of:
        a) helping WebTeam to improve squeak.org
        b) help fixing the in-image-bug-reporting-mechanism to point to suggest
mantis
        c) ask how to help in any other way or (gasp) actually just do it

/Göran

PS. Not on the board anymore so I can actually write a post like this!
Nice. Ok, so I am in a slightly bad mood for the moment - sue me. I will
be friendlier when I get more sleep. ;)

Reply | Threaded
Open this post in threaded view
|

Re: bugs on mantis: who assigns them ?

timrowledge

On 7-Mar-06, at 4:06 PM, [hidden email] wrote:
>
> PS. Not on the board anymore so I can actually write a post like this!
> Nice. Ok, so I am in a slightly bad mood for the moment - sue me. I  
> will
> be friendlier when I get more sleep. ;)

Nobody told me I'd have to be *nice* just because I'm on the board. I  
don't *think* so! One of the few privileges remaining to the  
aristocracy is being able to be rude and have it count as  
eccentricity....

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Useful random insult:- Moves his lips to pretend he's reading.



Reply | Threaded
Open this post in threaded view
|

The grand update stream. (was: bugs on mantis)

Alan Grimes
In reply to this post by Göran Krampe
[hidden email] wrote:

> Alan Grimes <[hidden email]> wrote:
>
>>Here's what I do when I find a bug in squeak:
>
> [SNIP of blablabla]
>
> You forgot:
>
> 8. Bitch on squeak-dev instead of:
> a) helping WebTeam to improve squeak.org
> b) help fixing the in-image-bug-reporting-mechanism to point to suggest
> mantis
> c) ask how to help in any other way or (gasp) actually just do it

Okay, I can play this game.

I was about ready to concede when I remembered what happens when I do
try to contribute.

A fair number of moons ago, I tweaked the Sokoban Morph to within an
inch of it's life and tried to publish it on Squeak's version control
archive (I can't remember it's name...). While some might take issue
with some of my stylistic decisions, the code did work and demonstrated
a clear improvment in the quality of gameplay. (Implementing my changes
from scratch would take about 20 hours of work..) I submitted this to
whom I thought was the maintainer. He liked some of my changes but
preferred a different visual style... I'm really not sure what happened
to that version... A few weeks later a version of Sokoban appeared in
the mainline. It was based on the same suckey code that had inspired me
to fix it in the first place!

That isn't to say that none of my changes are appreciated. I made
several enhancements to B3DMatrix (If I remember the class name
correctly...) that either simplified the call graph, removed redundant
methods, or helped reign in excessive GCing... One person noticed one of
my changes and is probably enjoying it on his system right now. The rest
of you aren't.

Contribute to Squeak? What's the point... Your enhancements and fixes
vanish into the aether and never get used.

Squeak is still a great system but all the cool things are happening
behind closed doors at the croquetproject... Ofcourse when 1.0 comes out
I'll have to back-port in all of the enhancements I've made to 0.3. =\


--
Don't let your schoolwork get in the way of your learning.

http://users.rcn.com/alangrimes/

Reply | Threaded
Open this post in threaded view
|

Re: The grand update stream. (was: bugs on mantis)

stéphane ducasse-2
Hi alan

you should not mixed Squeak and Sokoban or any goodies.
Have you contacted his author robert hirsfeld
May be is simply did not like your changes?

Stef

On 8 mars 06, at 03:57, Alan Grimes wrote:

> [hidden email] wrote:
>> Alan Grimes <[hidden email]> wrote:
>>
>>> Here's what I do when I find a bug in squeak:
>>
>> [SNIP of blablabla]
>>
>> You forgot:
>>
>> 8. Bitch on squeak-dev instead of:
>> a) helping WebTeam to improve squeak.org
>> b) help fixing the in-image-bug-reporting-mechanism to point to  
>> suggest
>> mantis
>> c) ask how to help in any other way or (gasp) actually just do it
>
> Okay, I can play this game.
>
> I was about ready to concede when I remembered what happens when I do
> try to contribute.
>
> A fair number of moons ago, I tweaked the Sokoban Morph to within an
> inch of it's life and tried to publish it on Squeak's version control
> archive (I can't remember it's name...). While some might take issue
> with some of my stylistic decisions, the code did work and  
> demonstrated
> a clear improvment in the quality of gameplay. (Implementing my  
> changes
> from scratch would take about 20 hours of work..) I submitted this to
> whom I thought was the maintainer. He liked some of my changes but
> preferred a different visual style... I'm really not sure what  
> happened
> to that version... A few weeks later a version of Sokoban appeared in
> the mainline. It was based on the same suckey code that had  
> inspired me
> to fix it in the first place!
>
> That isn't to say that none of my changes are appreciated. I made
> several enhancements to B3DMatrix (If I remember the class name
> correctly...) that either simplified the call graph, removed redundant
> methods, or helped reign in excessive GCing... One person noticed  
> one of
> my changes and is probably enjoying it on his system right now. The  
> rest
> of you aren't.
>
> Contribute to Squeak? What's the point... Your enhancements and fixes
> vanish into the aether and never get used.
>
> Squeak is still a great system but all the cool things are happening
> behind closed doors at the croquetproject... Ofcourse when 1.0  
> comes out
> I'll have to back-port in all of the enhancements I've made to 0.3. =\
>
>
> --
> Don't let your schoolwork get in the way of your learning.
>
> http://users.rcn.com/alangrimes/
>


Reply | Threaded
Open this post in threaded view
|

Re: bugs on mantis: who assigns them ?

Dan Corneanu
In reply to this post by Alan Grimes
I see I have managed to kick off some discussions on the issue of
bugs handling / fixing. This is gooood ...

Alan Grimes wrote:

> Here's what I do when I find a bug in squeak:
>
> 1. 90% of the time fix it myself without telling anyone, the rest I
> can't fix and I try to report...
>
> 2. I play around with squeak's built-in reporting system and get yelled
> at to post it on Mantis instead...
>
> 3. Scratch my head and wonder what a carnivorous insect has to do with
> my bug...
>
> 4. Wait 4 days...
>
> 5. In the middle of a dream, while my mind is making random
> associations, that mantis is actually squeak's bug tracking system.
>
> 6. go to one of the well known squeak sites such as squeak.org looking
> for a convenient link to the site. -- which fails...

Actually there is a link on squeak.org
http://www.squeak.org/Community/
Anyhow, I would say it would be great to have a link to the Bug
Database in the Links panel (on the right side). I have found myself
looking for it a few times...

>
> 7. google the damn thing yet again... (except that I'm beyond caring at
> this point...)
>
>


Reply | Threaded
Open this post in threaded view
|

Re: The grand update stream. (was: bugs on mantis)

Ed Boyce
In reply to this post by Alan Grimes

> Squeak is still a great system but all the cool things are happening
> behind closed doors at the croquetproject... Ofcourse when 1.0 comes out
> I'll have to back-port in all of the enhancements I've made to 0.3. =\
>

Just curious ... what improvements have you been able to make to Jasmine?

Also, you may be interested to know that I am working on the Croquet
Consortium public portal, which will, among services, provide SVN for
Croquet's code and communal content after 1.0 is released, and the
development model moves out of the cathederal and into the bazaar.

    -- Ed


Reply | Threaded
Open this post in threaded view
|

RE: bugs on mantis: who assigns them ?

Ron Teitelbaum
In reply to this post by Dan Corneanu
> Alan Grimes wrote:


> > 3. Scratch my head and wonder what a carnivorous insect has to do with
> > my bug...

You know I'm still laughing, that was funny.  Good point though.

Ron Teitelbaum


Reply | Threaded
Open this post in threaded view
|

Some subjective requirements for a radically optimistic "Code-Wiki" (was: Re: bugs on mantis: who assigns them ?)

Markus Gälli-3
In reply to this post by Alan Grimes
Hi folks,

I am still waiting for a radically optimistic "wiki like"  
environment, where anybody (ok, say having at least the status of an  
apprentice on Squeak-People...) can change code of the current  
golden_and_shared_image anytime, ideally _always_ developing with it  
as the base for his (do we have a she on Squeak-People with at least  
apprentice status?) daily work.

A first rough description for a simple code-wiki architecture I'd  
like to use:
=============
1.) Some sandbox
        E.g. Accessing the file system from code that gets pushed into my  
image is a big no.

2.) Wiki features: Login, History, Changes, Rollback, Links To
        - Login with squeak-people account
        - Automatic versioning of methods and classes: When I save a method/
class in my browser, it gets stored as a new version in the central  
repository. (a tweaked squeaksource?)
                The new version is only pushed into other clients, when I release  
the package it resides in. (see 3.)).
                Other people can see it though if they browsed "versions" of the  
class/method.
        - History, changes and rollback of methods, classes and packages (or  
PackageInfo's as they somehow call them today)
        - Links to: Who needs that
                method, class, package

3.) Difference to wikis or Envy
        - A package knows whether it belongs to the _golden_and_shared_image  
or not
        - Packages do not get versioned, they only get released. As an  
airline company told me recently about my ticket: "Use it - or lose  
it" ;-)
        - Methods and classes get versioned automatically each time one  
changes/saves them, but they do not get released.
        - Methods and classes know whether they are part of a released package.
        - If a package gets released
                - it automatically gets a unique release id
                - it internally stores all release ids of all required packages  
(thus serving as some kind of loadable "config map" at the same time)
                - it gets pushed to every client using the shared environment (only  
if it belongs into the _golden_shared_image_ of course)

4.) A Notion of quality
        - Having the idea that any apprentice could push a new release of  
some package into my current image might naturally lead to more test  
awareness.
        One could think about being able to release a package only if
                -at least all changes (to start from somewhere) are also covered by  
a green test.
                -all tests of all _depending_ packages also still work, whether  
they are in the _golden and shared_ image or not
        -The more a package is down to the system, the more other packages  
will depend on it, and the higher the status (apprentice, journeyer  
or master) of the changing person must be.
        -Having the notion of package ownership the owner shall definitely  
at least automatically get a mail, if a new version of his/her  
package was released

PLEASE: Feel free to play with these ideas (or feel free to let your  
students play with it) or even implement them- I didn't even have  
time to write them down... ;-)
There are some efforts to do sth like that in Croquet I have heard,  
but I don't know anything specific....
===================
Btw: Ward Cunningham is working for the "Eclipse committer community"  
and not for MS since Oct 2005:

"To date, the efforts of the Eclipse Foundation in support of the  
committer community have been primarily around providing  
infrastructure and process. However, a high functioning committer  
community is about more than just sharing servers and following a  
common process. A high functioning committer community is about  
collaboration and cooperation between the project silos. Although the  
Councils do an admirable job of co-ordinating the activities of the  
many Eclipse projects, what is needed is a culture of collaboration  
and cooperation. This is especially true today, as Eclipse grows  
rapidly with new projects and new committers.

To help cultivate this committer culture, Ward Cunningham is joining  
the Eclipse Foundation as Director, Committer Community Development.  
Ward's track record of invention in areas such as wikis, patterns and  
agile development are known worldwide. His current interests in open  
source and developing communities of developers are a perfect match  
for the work we need to do at Eclipse. Ward will lead the effort to  
create a more cohesive Eclipse committer community by working with  
developers in order to enhance Eclipse as "the place to be".

http://www.eclipse.org/org/press-release/20051019cunningham.html

So let's be faster than them :-)

Cheers,

Markus


On Mar 8, 2006, at 1:37 AM, Alan Grimes wrote:

> Here's what I do when I find a bug in squeak:
>
> 1. 90% of the time fix it myself without telling anyone, the rest I
> can't fix and I try to report...
>
> 2. I play around with squeak's built-in reporting system and get  
> yelled
> at to post it on Mantis instead...
>
> 3. Scratch my head and wonder what a carnivorous insect has to do with
> my bug...
>
> 4. Wait 4 days...
>
> 5. In the middle of a dream, while my mind is making random
> associations, that mantis is actually squeak's bug tracking system.
>
> 6. go to one of the well known squeak sites such as squeak.org looking
> for a convenient link to the site. -- which fails...
>
> 7. google the damn thing yet again... (except that I'm beyond  
> caring at
> this point...)
>
>
> --
> Don't let your schoolwork get in the way of your learning.
>
> http://users.rcn.com/alangrimes/
>


Reply | Threaded
Open this post in threaded view
|

Re: Some subjective requirements for a radically optimistic "Code-Wiki" (was: Re: bugs on mantis: who assigns them ?)

timrowledge

On 8-Mar-06, at 7:05 AM, Markus Gaelli wrote:

> Hi folks,
>
> I am still waiting for a radically optimistic "wiki like"  
> environment, where anybody (ok, say having at least the status of  
> an apprentice on Squeak-People...) can change code of the current  
> golden_and_shared_image anytime, ideally _always_ developing with  
> it as the base for his (do we have a she on Squeak-People with at  
> least apprentice status?) daily work.
Given the number of mistakes even the best of the Master rated people  
make I'd really  not like to live in a world where code could just be  
stuffed in by anyone. Shudder.  I mean for goodness sake, I've been  
doing this continuously for 23 years and still screw up.


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: SDP: Search and Destroy Pointer



Reply | Threaded
Open this post in threaded view
|

Re: Ask not what the board can do for you, ask rather what you can do for us all

Damien Cassou-3
In reply to this post by timrowledge
> Job 3: assign it to someone plausible
> A lot of the time it is quickly obvious where the problem lies and you
> can assign the report to the right people. If you don't know the right
> assignee, change the report status to feedback and assign it to your
> best guess.  It's not like you're ordering the person to do work.
> What we could do with in the Mantis setup is a more useful list of
> assignable names; I'd really prefer to see 'VM guys', 'Collections
> folks', 'Windows weenie' than 'fred', 'jkr' etc. Roles are better than
> names for this purpose.

It seems I can't change assignment for my bugs. They are automatically
affected to Ken. Do I need some permissions ?


--
Damien Cassou


Reply | Threaded
Open this post in threaded view
|

Re: Ask not what the board can do for you, ask rather what you can do for us all

Ken Causey-3
On Wed, 2006-03-08 at 22:14 +0100, Damien Cassou wrote:

> > Job 3: assign it to someone plausible
> > A lot of the time it is quickly obvious where the problem lies and you
> > can assign the report to the right people. If you don't know the right
> > assignee, change the report status to feedback and assign it to your
> > best guess.  It's not like you're ordering the person to do work.
> > What we could do with in the Mantis setup is a more useful list of
> > assignable names; I'd really prefer to see 'VM guys', 'Collections
> > folks', 'Windows weenie' than 'fred', 'jkr' etc. Roles are better than
> > names for this purpose.
>
> It seems I can't change assignment for my bugs. They are automatically
> affected to Ken. Do I need some permissions ?
>
As I answered for someone else recently: You don't directly assign bugs,
you set the Category field to the appropriate value which assigns it to
an appropriate team.

Ken

P.S. If you don't choose a category and leave it as Any then it is
assigned to me so that I'm notified and then I can go in and set the
category.



signature.asc (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Ask not what the board can do for you, ask rather what you can do for us all

timrowledge

On 8-Mar-06, at 1:21 PM, Ken Causey wrote:

> On Wed, 2006-03-08 at 22:14 +0100, Damien Cassou wrote:
>>> Job 3: assign it to someone plausible
>>> A lot of the time it is quickly obvious where the problem lies  
>>> and you
>>> can assign the report to the right people. If you don't know the  
>>> right
>>> assignee, change the report status to feedback and assign it to your
>>> best guess.  It's not like you're ordering the person to do work.
>>> What we could do with in the Mantis setup is a more useful list of
>>> assignable names; I'd really prefer to see 'VM guys', 'Collections
>>> folks', 'Windows weenie' than 'fred', 'jkr' etc. Roles are better  
>>> than
>>> names for this purpose.
>>
>> It seems I can't change assignment for my bugs. They are  
>> automatically
>> affected to Ken. Do I need some permissions ?
>>
>
> As I answered for someone else recently: You don't directly assign  
> bugs,
> you set the Category field to the appropriate value which assigns  
> it to
> an appropriate team.
Ah - I see. That's actually a pretty good match to assigning to a  
role then, which is nice. So let's revise Job 3 to

Job 3: assign it to someone plausible
A lot of the time it is quickly obvious where the problem lies and you
can assign the report to the right people. The best way to do this is  
to choose a plausible seeming entry from the Category list which  in  
effect assigns the issue to a team.

There's also a useful meta-Job that anyone can do; look around for  
reports that seem to be abandoned and see if you can rattle them  
around a bit. Email the people who reported or commented on it; ask  
if there is still any interest. Make a nuisance of yourself - most of  
us can do *that* well enough.



tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: TVO: Type Various Obscenities



Reply | Threaded
Open this post in threaded view
|

Re: The grand update stream.

Alan Grimes
In reply to this post by Ed Boyce
> Just curious ... what improvements have you been able to make to Jasmine?

3D models use alot of matrix multiplies... Usually this is done with
three physical matrices. Each multiply creates a new matrix for the
result... If the code does many many multiplies such as a multi-jointed
3D model and camera motions, then quite a bit of memory gets burned,
(8x16 bytes + headers for each discarded matrix). I wrapped one of the
primatives and made a "multiply and discard" method which overwrote one
of the operands with the result. This new code can replace many
instances of the old 3-way call hence reducing the time spent in the GC...

I also identified two methods in the matrix class which did the exact
same thing, I removed the one with the larger call graph and re-named
the other. (it had fewer senders...)

Most of my changes dealt with these two items...

/ me tried to exparament with Big Mesh teapot but ran into the flaming
signed pointer bug... =P

the video drivers I curently have installed has some texture bugs too. =\

reviewing my changes, I see I did a lot of scope demotions too.
Unfortunately the compiler doesn't seem to honor scope in such a way
that it could be a performance boost. =\ (If a variable is only used in
a conditional branch, it doesn't need to exist unless the branch is
executed... )

I attached the version I currently have on my system. Note the removed
methods.


--
Don't let your schoolwork get in the way of your learning.

http://users.rcn.com/alangrimes/

'From Jasmine-rc1 of 7 October 2004 [latest update: #280] on 8 March 2006 at 8:56:29 pm'!
B3DFloatArray variableWordSubclass: #B3DMatrix4x4
        instanceVariableNames: ''
        classVariableNames: 'B3DIdentityMatrix B3DZeroMatrix '
        poolDictionaries: ''
        category: 'Balloon3D-Kernel-Vectors'!
!B3DMatrix4x4 commentStamp: '<historical>' prior: 0!
I represent a general 4x4 transformation matrix commonly used in computer graphics.!


!B3DMatrix4x4 methodsFor: '*Croquet' stamp: 'das 9/17/2003 13:09'!
localBoxToGlobal: aTBox

        ^TBox min: (self localPointToGlobal: aTBox min) max: (self localPointToGlobal: aTBox max).! !

!B3DMatrix4x4 methodsFor: '*Croquet' stamp: 'ar 10/1/2004 09:53'!
orientation
"This is used to return just the orientation part of the matrix.The translation part is 0.0."
        | mat |

        mat _ self clone.
        mat translationX: 0.0 y: 0.0 z: 0.0.
        ^ mat.! !


!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'jsp 2/11/1999 14:09'!
at: i at: j
        ^ self at: ((i - 1) * 4 + j).
! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'jsp 2/11/1999 14:09'!
at: i at: j put: aValue
        ^ self at: ((i - 1) * 4 + j) put: aValue.
! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'atg 10/17/2005 10:11'!
pitchYawRoll
        "Assume the receiver describes an orthonormal 3x3 matrix"
        ^ self a23 negated arcSin radiansToDegrees @ (self a13 arcTan: self a33) radiansToDegrees @ (    self a21 arcTan: self a22) radiansToDegrees! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'atg 10/13/2005 19:55'!
pitchYawRoll: ypr
        "Assume the receiver describes an orthonormal 3x3 matrix"
        self
                loadFrom: (((self class identity rotationAroundZ: ypr z)
                                multiplyAndDiscard: ((self class identity rotationAroundY: ypr y)
                                                multiplyAndDiscard: (self class identity rotationAroundX: ypr x)))
                                translation: self translation)! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'atg 10/18/2005 18:37'!
rotation
        "Return the angular rotation around each axis of the matrix"
        | vRow1 vRow2 vRow3 vAngles |
        vRow1 _ self row1.
        vRow1 normalize.
        vRow2 _ self row2.
        vRow2 _ vRow2 + (vRow1 * (vRow1 dot: vRow2) negated).
        vRow2 normalize.
        vRow3 _ self row3.
        vRow3 _ vRow3 + (vRow1 * (vRow1 dot: vRow3) negated).
        vRow3 _ vRow3 + (vRow2 * (vRow2 dot: vRow3) negated).
        vRow3 normalize.
        (vRow1
                        dot: (vRow2 cross: vRow3))
                        < 0.0
                ifTrue: [vRow1 _ vRow1 negated.
                        vRow2 _ vRow2 negated.
                        vRow3 _ vRow3 negated].
        vAngles _ B3DVector3 new.
        vAngles at: 2 put: (vRow1 at: 3) negated arcSin.
        (vAngles at: 2) cos ~= 0.0
                ifTrue: [vAngles
                                at: 1
                                put: ((vRow2 at: 3)
                                                arcTan: (vRow3 at: 3)).
                        vAngles
                                at: 3
                                put: ((vRow1 at: 2)
                                                arcTan: (vRow1 at: 1))]
                ifFalse: [vAngles
                                at: 1
                                put: ((vRow2 at: 1)
                                                arcTan: (vRow2 at: 2)).
                        vAngles at: 3 put: 0.0].
        vAngles at: 1 put: (vAngles at: 1) radiansToDegrees.
        vAngles at: 2 put: (vAngles at: 2) radiansToDegrees.
        vAngles at: 3 put: (vAngles at: 3) radiansToDegrees.
        ^ vAngles! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'jsp 2/24/1999 09:46'!
rotation: aVector
        | xRot yRot zRot cosPitch sinPitch cosYaw sinYaw cosRoll sinRoll |

        xRot _ (aVector x) degreesToRadians.
        yRot _ (aVector y) degreesToRadians.
        zRot _ (aVector z) degreesToRadians.

        cosPitch _ xRot cos.
        sinPitch _ xRot sin.
        cosYaw _ yRot cos.
        sinYaw _ yRot sin.
        cosRoll _ zRot cos.
        sinRoll _ zRot sin.

        self a11: (cosRoll*cosYaw).
        self a12: (sinRoll*cosYaw).
        self a13: (sinYaw negated).

        self a21: ((cosRoll*sinYaw*sinPitch) - (sinRoll*cosPitch)).
        self a22: ((cosRoll*cosPitch) + (sinRoll*sinYaw*sinPitch)).
        self a23: (cosYaw*sinPitch).
        self a31: ((cosRoll*sinYaw*cosPitch) + (sinRoll*sinPitch)).
        self a32: ((sinRoll*sinYaw*cosPitch) - (cosRoll*sinPitch)).
        self a33: (cosYaw*cosPitch).

        ^ self.
! !

!B3DMatrix4x4 methodsFor: 'accessing'!
rotation: anAngle around: aVector3
        "set up a rotation matrix around the direction aVector3"

        self loadFrom: (B3DRotation angle: anAngle axis: aVector3) asMatrix4x4! !

!B3DMatrix4x4 methodsFor: 'accessing'!
rotation: anAngle aroundX: xValue y: yValue z: zValue
        "set up a rotation matrix around the direction x/y/z"
        ^self rotation: anAngle around:(B3DVector3 with: xValue with: yValue with: zValue)! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'ar 2/1/1999 21:34'!
rotationAroundX: anAngle
        | rad s c |
        rad := anAngle degreesToRadians.
        s := rad sin.
        c := rad cos.
        self a22: c.
        self a23: s negated.
        self a33: c.
        self a32: s.
        ^self! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'ar 2/1/1999 21:34'!
rotationAroundY: anAngle
        | rad s c |
        rad := anAngle degreesToRadians.
        s := rad sin.
        c := rad cos.
        self a11: c.
        self a13: s.
        self a33: c.
        self a31: s negated.
        ^self! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'ar 2/1/1999 21:35'!
rotationAroundZ: anAngle
        | rad s c |
        rad := anAngle degreesToRadians.
        s := rad sin.
        c := rad cos.
        self a11: c.
        self a12: s negated.
        self a22: c.
        self a21: s.
        ^self! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'ar 4/16/1999 21:51'!
squaredDistanceFrom: aMatrix
        | sum |
        sum _ 0.0.
        1 to: 4 do:[:i|
                1 to: 4 do:[:j|
                        sum _ sum + ((self at: i at: j) - (aMatrix at: i at: j)) squared]].
        ^sum! !

!B3DMatrix4x4 methodsFor: 'accessing'!
translation

        ^(B3DVector3 x: self a14 y: self a24 z: self a34)! !

!B3DMatrix4x4 methodsFor: 'accessing' stamp: 'atg 10/12/2005 21:51'!
translationX: xValue y: yValue z: zValue
        ^ self a14: xValue;
                 a24: yValue;
                 a34: zValue! !


!B3DMatrix4x4 methodsFor: 'arithmetic' stamp: 'ar 2/2/2001 15:47'!
+ aB3DMatrix
        "Optimized for Matrix/Matrix operations"
        <primitive: 'primitiveAddFloatArray' module: 'FloatArrayPlugin'>
        ^super + aB3DMatrix! !

!B3DMatrix4x4 methodsFor: 'arithmetic' stamp: 'ar 2/2/2001 15:47'!
- aB3DMatrix
        "Optimized for Matrix/Matrix operations"
        <primitive: 'primitiveSubFloatArray' module: 'FloatArrayPlugin'>
        ^super - aB3DMatrix! !


!B3DMatrix4x4 methodsFor: 'comparing' stamp: 'ar 2/1/1999 21:53'!
squaredErrorDistanceTo: anotherMatrix
        | result temp |
        result := self - anotherMatrix.
        temp := 0.
        1 to: 4 do: [:i | 1 to: 4 do: [:j| temp := temp + ((result at: i-1*4+j) squared)]].
        ^temp sqrt.! !


!B3DMatrix4x4 methodsFor: 'converting'!
asMatrix4x4
        ^self! !

!B3DMatrix4x4 methodsFor: 'converting' stamp: 'jsp 3/5/1999 15:31'!
asQuaternion
        "Convert the matrix to a quaternion"

        | x y z a a2 x2 y2 a4 |

        a2 _ 0.25 * (1.0 + (self a11) + (self a22) + (self a33)).

        (a2 > 0) ifTrue: [
                                                a _ a2 sqrt.
                                                a4 _ 4.0 * a.
                                                x _ ((self a32) - (self a23)) / a4.
                                                y _ ((self a13) - (self a31)) / a4.
                                                z _ ((self a21) - (self a12)) / a4.
                                        ]
                        ifFalse: [
                                                a _ 0.
                                                x2 _ -0.5 * ((self a22) + (self a33)).
                                                (x2 > 0) ifTrue: [
                                                                                        x _ x2 sqrt.
                                                                                        x2 _ 2 * x.
                                                                                        y _ (self a21) / x2.
                                                                                        z _ (self a31) / x2.
                                                                                ]
                                                                ifFalse: [
                                                                                        x _ 0.
                                                                                        y2 _ 0.5 * (1.0 - (self a33)).
                                                                                        (y2 > 0) ifTrue: [
                                                                                                                                y _ y2 sqrt.
                                                                                                                                y2 _ 2 * y.
                                                                                                                                z _ (self a32) / y2.
                                                                                                                        ]
                                                                                                        ifFalse: [
                                                                                                                                y _ 0.0.
                                                                                                                                z _ 1.0.
                                                                                                                        ]
                                                                                ]
                                        ].

        ^ (B3DRotation a: a b: x c: y d: z).
! !


!B3DMatrix4x4 methodsFor: 'double dispatching' stamp: 'ar 2/1/1999 21:49'!
printOn: aStream
        "Print the receiver on aStream"
        1 to: 4 do:[:r|
                1 to: 4 do:[:c|
                        (self at: r-1*4+c) printOn: aStream.
                        aStream nextPut: Character space].
                (r < 4) ifTrue:[aStream nextPut: Character cr]].! !

!B3DMatrix4x4 methodsFor: 'double dispatching' stamp: 'ar 2/8/1999 20:11'!
productFromMatrix4x4: matrix
        "Multiply a 4x4 matrix with the receiver."
        | result |
        result := self class new.
        result a11: ((matrix a11 * self a11) + (matrix a12 * self a21) +
                                (matrix a13 * self a31) + (matrix a14 * self a41)).
        result a12: ((matrix a11 * self a12) + (matrix a12 * self a22) +
                                (matrix a13 * self a32) + (matrix a14 * self a42)).
        result a13: ((matrix a11 * self a13) + (matrix a12 * self a23) +
                                (matrix a13 * self a33) + (matrix a14 * self a43)).
        result a14: ((matrix a11 * self a14) + (matrix a12 * self a24) +
                                (matrix a13 * self a34) + (matrix a14 * self a44)).

        result a21: ((matrix a21 * self a11) + (matrix a22 * self a21) +
                                (matrix a23 * self a31) + (matrix a24 * self a41)).
        result a22: ((matrix a21 * self a12) + (matrix a22 * self a22) +
                                (matrix a23 * self a32) + (matrix a24 * self a42)).
        result a23: ((matrix a21 * self a13) + (matrix a22 * self a23) +
                                (matrix a23 * self a33) + (matrix a24 * self a43)).
        result a24: ((matrix a21 * self a14) + (matrix a22 * self a24) +
                                (matrix a23 * self a34) + (matrix a24 * self a44)).

        result a31: ((matrix a31 * self a11) + (matrix a32 * self a21) +
                                (matrix a33 * self a31) + (matrix a34 * self a41)).
        result a32: ((matrix a31 * self a12) + (matrix a32 * self a22) +
                                (matrix a33 * self a32) + (matrix a34 * self a42)).
        result a33: ((matrix a31 * self a13) + (matrix a32 * self a23) +
                                (matrix a33 * self a33) + (matrix a34 * self a43)).
        result a34: ((matrix a31 * self a14) + (matrix a32 * self a24) +
                                (matrix a33 * self a34) + (matrix a34 * self a44)).

        result a41: ((matrix a41 * self a11) + (matrix a42 * self a21) +
                                (matrix a43 * self a31) + (matrix a44 * self a41)).
        result a42: ((matrix a41 * self a12) + (matrix a42 * self a22) +
                                (matrix a43 * self a32) + (matrix a44 * self a42)).
        result a43: ((matrix a41 * self a13) + (matrix a42 * self a23) +
                                (matrix a43 * self a33) + (matrix a44 * self a43)).
        result a44: ((matrix a41 * self a14) + (matrix a42 * self a24) +
                                (matrix a43 * self a34) + (matrix a44 * self a44)).

        ^result! !

!B3DMatrix4x4 methodsFor: 'double dispatching'!
productFromVector3: aVector3
        "Multiply aVector (temporarily converted to 4D) with the receiver"
        | x y z rx ry rz rw |
        x := aVector3 x.
        y := aVector3 y.
        z := aVector3 z.

        rx := (x * self a11) + (y * self a21) + (z * self a31) + self a41.
        ry := (x * self a12) + (y * self a22) + (z * self a32) + self a42.
        rz := (x * self a13) + (y * self a23) + (z * self a33) + self a43.
        rw := (x * self a14) + (y * self a24) + (z * self a34) + self a44.

        ^B3DVector3 x:(rx/rw) y: (ry/rw) z: (rz/rw)! !

!B3DMatrix4x4 methodsFor: 'double dispatching'!
productFromVector4: aVector4
        "Multiply aVector with the receiver"
        | x y z w rx ry rz rw |
        x := aVector4 x.
        y := aVector4 y.
        z := aVector4 z.
        w := aVector4 w.

        rx := (x * self a11) + (y * self a21) + (z * self a31) + (w * self a41).
        ry := (x * self a12) + (y * self a22) + (z * self a32) + (w * self a42).
        rz := (x * self a13) + (y * self a23) + (z * self a33) + (w * self a43).
        rw := (x * self a14) + (y * self a24) + (z * self a34) + (w * self a44).

        ^B3DVector4 x:rx y: ry z: rz w: rw! !


!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a11
        "Return the element a11"
        ^self at: 1! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a11: aNumber
        "Store the element a11"
        self at: 1 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a12
        "Return the element a12"
        ^self at: 2! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a12: aNumber
        "Store the element a12"
        self at: 2 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a13
        "Return the element a13"
        ^self at: 3! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a13: aNumber
        "Store the element a13"
        self at: 3 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a14
        "Return the element a14"
        ^self at: 4! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a14: aNumber
        "Store the element a14"
        self at: 4 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a21
        "Return the element a21"
        ^self at: 5! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a21: aNumber
        "Store the element a21"
        self at: 5 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a22
        "Return the element a22"
        ^self at: 6! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a22: aNumber
        "Store the element a22"
        self at: 6 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a23
        "Return the element a23"
        ^self at: 7! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a23: aNumber
        "Store the element a23"
        self at: 7 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a24
        "Return the element a24"
        ^self at: 8! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a24: aNumber
        "Store the element a24"
        self at: 8 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a31
        "Return the element a31"
        ^self at: 9! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a31: aNumber
        "Store the element a31"
        self at: 9 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a32
        "Return the element a32"
        ^self at: 10! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a32: aNumber
        "Store the element a32"
        self at: 10 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a33
        "Return the element a33"
        ^self at: 11! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a33: aNumber
        "Store the element a33"
        self at: 11 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a34
        "Return the element a34"
        ^self at: 12! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a34: aNumber
        "Store the element a34"
        self at: 12 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a41
        "Return the element a41"
        ^self at: 13! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a41: aNumber
        "Store the element a41"
        self at: 13 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a42
        "Return the element a42"
        ^self at: 14! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a42: aNumber
        "Store the element a42"
        self at: 14 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a43
        "Return the element a43"
        ^self at: 15! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a43: aNumber
        "Store the element a43"
        self at: 15 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:29'!
a44
        "Return the element a44"
        ^self at: 16! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'ar 2/1/1999 21:28'!
a44: aNumber
        "Store the element a44"
        self at: 16 put: aNumber! !

!B3DMatrix4x4 methodsFor: 'element-access' stamp: 'atg 10/13/2005 08:21'!
scalingX: xValue y: yValue z: zValue

        ^self a11: self a11 * xValue;
         a22: self a22 * yValue;
 a33: self a33 * zValue.! !


!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'ar 2/1/1999 21:26'!
setBSplineBase
        "Set the receiver to the BSpline base matrix"
        "for further information see:
                Foley, van Dam, Feiner, Hughes
                'Computer Graphics: Principles and Practice'
                Addison-Wesley Publishing Company
                Second Edition, pp. 505"
        self
                a11: -1.0 / 6.0; a12: 3.0 / 6.0; a13: -3.0 / 6.0; a14: 1.0 / 6.0;
                a21: 3.0 / 6.0; a22: -6.0 / 6.0; a23: 3.0 / 6.0; a24: 0.0 / 6.0;
                a31: -3.0 / 6.0; a32: 0.0 / 6.0; a33: 3.0 / 6.0; a34: 0.0 / 6.0;
                a41: 1.0 / 6.0; a42: 4.0 / 6.0; a43: 1.0 / 6.0; a44: 0.0 / 6.0
! !

!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'ar 2/1/1999 21:26'!
setBetaSplineBaseBias: beta1 tension: beta2
        "Set the receiver to the betaSpline base matrix
        if beta1=1 and beta2=0 then the bSpline base matrix will be returned"
        "for further information see:
                Foley, van Dam, Feiner, Hughes
                'Computer Graphics: Principles and Practice'
                Addison-Wesley Publishing Company
                Second Edition, pp. 505"
        | b12 b13 delta |
        b12 := beta1 * beta1.
        b13 := beta1 * b12.
        delta := 1.0 / (beta2 + (2.0 * b13) + 4.0 * (b12 + beta1) +2.0).
       
        self
                a11: delta * -2.0 * b13;
                a12: delta * 2.0 * (beta2 + b13 + b12 + beta1);
                a13: delta * -2.0 * (beta2 + b12 + beta1 + 1.0);
                a14: delta * 2.0;
                a21: delta * 6.0 * b13;
                a22: delta * -3.0 * (beta2 + (2.0 * (b13 + b12)));
                a23: delta * 3.0 * (beta2 + (2.0 * b12));
                a24: 0.0;
                a31: delta * -6.0 * b13;
                a32: delta * 6.0 * (b13 - beta1);
                a33: delta * 6.0 * beta1;
                a34: 0.0;
                a41: delta * 2.0 * b13;
                a42: delta * (beta2 + 4.0 * (b12 + beta1));
                a43: delta * 2.0;
                a44: 0.0
! !

!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'ar 2/1/1999 21:27'!
setBezierBase
        "Set the receiver to the bezier base matrix"
        "for further information see:
                Foley, van Dam, Feiner, Hughes
                'Computer Graphics: Principles and Practice'
                Addison-Wesley Publishing Company
                Second Edition, pp. 505"
        self
                a11: -1.0; a12: 3.0; a13: -3.0; a14: 1.0;
                a21: 3.0; a22: -6.0; a23: 3.0; a24: 0.0;
                a31: -3.0; a32: 3.0; a33: 0.0; a34: 0.0;
                a41: 1.0; a42: 0.0; a43: 0.0; a44: 0.0! !

!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'ar 2/1/1999 21:27'!
setCardinalBase
        "Set the receiver to the cardinal spline base matrix - just catmull * 2"
        "for further information see:
                Foley, van Dam, Feiner, Hughes
                'Computer Graphics: Principles and Practice'
                Addison-Wesley Publishing Company
                Second Edition, pp. 505"
        self
                a11: -1.0; a12: 3.0; a13: -3.0; a14: 1.0;
                a21: 2.0; a22: -5.0; a23: 4.0; a24: -1.0;
                a31: -1.0; a32: 0.0; a33: 1.0; a34: 0.0;
                a41: 0.0; a42: 2.0; a43: 0.0; a44: 0.0
! !

!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'ar 2/1/1999 21:27'!
setCatmullBase
        "Set the receiver to the Catmull-Rom base matrix"
        "for further information see:
                Foley, van Dam, Feiner, Hughes
                'Computer Graphics: Principles and Practice'
                Addison-Wesley Publishing Company
                Second Edition, pp. 505"
        self
                a11: -0.5; a12: 1.5; a13: -1.5; a14: 0.5;
                a21: 1.0; a22: -2.5; a23: 2.0; a24: -0.5;
                a31: -0.5; a32: 0.0; a33: 0.5; a34: 0.0;
                a41: 0.0; a42: 1.0; a43: 0.0; a44: 0.0
! !

!B3DMatrix4x4 methodsFor: 'initialize'!
setIdentity
        "Set the receiver to the identity matrix"
        self loadFrom: B3DIdentityMatrix! !

!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'ar 2/1/1999 21:27'!
setPolylineBase
        "Set the receiver to the polyline base matrix :)"
        self
                a11: 0.0; a12: 0.0; a13: 0.0; a14: 0.0;
                a21: 0.0; a22: 0.0; a23: 0.0; a24: 0.0;
                a31: 0.0; a32: -1.0; a33: 1.0; a34: 0.0;
                a41: 0.0; a42: 1.0; a43: 0.0; a44: 0.0
! !

!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'ar 2/15/1999 02:55'!
setScale: aVector
        self
                a11: aVector x;
                a22: aVector y;
                a33: aVector z! !

!B3DMatrix4x4 methodsFor: 'initialize'!
setZero
        "Set the receiver to the zero matrix"
        self loadFrom: B3DZeroMatrix! !

!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'das 5/16/2002 11:11'!
skew: vector
        "Set the skew-symetric matrix up"
        self a21: vector z.
        self a12: vector z negated.
        self a31: vector y negated.
        self a13: vector y.
        self a32: vector x.
        self a23: vector x negated.
! !

!B3DMatrix4x4 methodsFor: 'initialize' stamp: 'das 2/6/2005 03:53'!
up: u at: a

        | side up at |
        side _ (a cross: u) normalized negated.
        up _ (side cross: a) normalized negated.
        at _ a normalized.
        self a11: side x.
        self a21: side y.
        self a31: side z.
        self a12: up x.
        self a22: up y.
        self a32: up z.
        self a13: at x.
        self a23: at y.
        self a33: at z.
        self a44: 1.0.
! !


!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 12/11/2002 14:35'!
column1
        "Return column 1"

        ^ (B3DVector3 x: (self a11) y: (self a21) z: (self a31)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 12/11/2002 14:37'!
column1: col
        "Set column 1"
        self a11: col x.
        self a21: col y.
        self a31: col z.
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 12/11/2002 14:36'!
column2
        "Return column 2"

        ^ (B3DVector3 x: (self a12) y: (self a22) z: (self a32)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 12/11/2002 14:37'!
column2: col
        "Set column 2"

        self a12: col x.
        self a22: col y.
        self a32: col z.
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 12/11/2002 14:37'!
column3
        "Return column 3"

        ^ (B3DVector3 x: (self a13) y: (self a23) z: (self a33)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 12/11/2002 14:37'!
column3: col
        "Set column 3"

        self a13: col x.
        self a23: col y.
        self a33: col z.
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 10/19/2004 22:00'!
lookAt
        "Return column 3"

        ^ (B3DVector3 x: (self a13) y: (self a23) z: (self a33)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 10/19/2004 22:01'!
lookSide
        "Return column 1"

        ^ (B3DVector3 x: (self a11) y: (self a21) z: (self a31)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 10/19/2004 22:01'!
lookUp
        "Return column 2"

        ^ (B3DVector3 x: (self a12) y: (self a22) z: (self a32)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'jsp 2/24/1999 17:10'!
row1
        "Return row 1"

        ^ (B3DVector3 x: (self a11) y: (self a12) z: (self a13)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 9/24/2002 10:27'!
row1: row
        "Set row 1"
        self a11: row x.
        self a12: row y.
        self a13: row z.
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'jsp 2/24/1999 17:11'!
row2
        "Return row 2"

        ^ (B3DVector3 x: (self a21) y: (self a22) z: (self a23)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 9/24/2002 10:28'!
row2: row
        "Set row 2"

        self a21: row x.
        self a22: row y.
        self a23: row z.
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'jsp 2/24/1999 17:11'!
row3
        "Return row 3"

        ^ (B3DVector3 x: (self a31) y: (self a32) z: (self a33)).
! !

!B3DMatrix4x4 methodsFor: 'row-access' stamp: 'das 9/24/2002 10:29'!
row3: row
        "Set row 3"

        self a31: row x.
        self a32: row y.
        self a33: row z.
! !


!B3DMatrix4x4 methodsFor: 'solving' stamp: 'atg 10/18/2005 19:16'!
inplaceDecomposeLU
        "Decompose the receiver in place by using gaussian elimination w/o
        pivot search"
        1
                to: 4
                do: [:j | "i-th equation (row)"
                        j + 1
                                to: 4
                                do: [:i | | x |
                                        x _ (self at: i at: j)
                                                                / (self at: j at: j).
                                        j
                                                to: 4
                                                do: [:k | self
                                                                at: i
                                                                at: k
                                                                put: (self at: i at: k)
                                                                                - ((self at: j at: k)
                                                                                                * x)].
                                        self
                                                at: i
                                                at: j
                                                put: x]]! !

!B3DMatrix4x4 methodsFor: 'solving' stamp: 'ar 5/22/2000 17:13'!
inplaceHouseHolderInvert
        "Solve the linear equation self * aVector = x by using HouseHolder's transformation.
        Note: This scheme is numerically better than using gaussian elimination even though it takes
        somewhat longer"
        | d x sigma beta sum s|
        <primitive:'b3dInplaceHouseHolderInvert' module:'Squeak3D'>
        x _ B3DMatrix4x4 identity.
        d _ B3DMatrix4x4 new.
        1 to: 4 do:[:j|
                sigma := 0.0.
                j to: 4 do:[:i| sigma := sigma + ((self at: i at: j) squared)].
                sigma isZero ifTrue:[^nil]. "matrix is singular"
                ((self at: j at: j) < 0.0)
                        ifTrue:[ s:= sigma sqrt]
                        ifFalse:[ s:= sigma sqrt negated].
                1 to: 4 do:[:r| d at: j at: r put: s].
                beta := 1.0 / ( s * (self at: j at: j) - sigma).
                self at: j at: j put: ((self at: j at: j) - s).
                "update remaining columns"
                j+1 to: 4 do:[:k|
                        sum := 0.0.
                        j to: 4 do:[:i| sum := sum + ((self at: i at: j) * (self at: i at: k))].
                        sum := sum * beta.
                        j to: 4 do:[:i|
                                self at: i at: k put: ((self at: i at: k) + ((self at: i at: j) * sum))]].
                "update vector"
                1 to: 4 do:[:r|
                        sum := nil.
                        j to: 4 do:[:i|
                                sum := sum isNil
                                        ifTrue:[(x at: i at: r) * (self at: i at: j)]
                                        ifFalse:[sum + ((x at: i at: r) * (self at: i at: j))]].
                        sum := sum * beta.
                        j to: 4 do:[:i|
                                x at: i at: r put:((x at: i at: r) + (sum * (self at: i at: j)))].
                ].
        ].
        "Now calculate result"
        1 to: 4 do:[:r|
                4 to: 1 by: -1 do:[:i|
                        i+1 to: 4 do:[:j|
                                x at: i at: r put: ((x at: i at: r) - ((x at: j at: r) * (self at: i at: j))) ].
                        x at: i at: r put: ((x at: i at: r) / (d at: i at: r))].
        ].
        self loadFrom: x.
        "Return receiver"! !

!B3DMatrix4x4 methodsFor: 'solving'!
inplaceHouseHolderTransform: aVector
        "Solve the linear equation self * aVector = x by using HouseHolder's transformation.
        Note: This scheme is numerically better than using gaussian elimination even though it takes
        somewhat longer"
        | d x sigma beta sum s|
        x := Array with: aVector x with: aVector y with: aVector z with: aVector w.
        d := Array new: 4.
        1 to: 4 do:[:j|
                sigma := 0.0.
                j to: 4 do:[:i| sigma := sigma + ((self at: i at: j) squared)].
                sigma isZero ifTrue:[^nil]. "matrix is singular"
                ((self at: j at: j) < 0.0)
                        ifTrue:[ s:= d at: j put: (sigma sqrt)]
                        ifFalse:[ s:= d at: j put: (sigma sqrt negated)].
                beta := 1.0 / ( s * (self at: j at: j) - sigma).
                self at: j at: j put: ((self at: j at: j) - s).
                "update remaining columns"
                j+1 to: 4 do:[:k|
                        sum := 0.0.
                        j to: 4 do:[:i| sum := sum + ((self at: i at: j) * (self at: i at: k))].
                        sum := sum * beta.
                        j to: 4 do:[:i|
                                self at: i at: k put: ((self at: i at: k) + ((self at: i at: j) * sum))]].
                "update vector"
                sum := nil.
                j to: 4 do:[:i|
                        sum := sum isNil
                                ifTrue:[(x at: i) * (self at: i at: j)]
                                ifFalse:[sum + ((x at: i) * (self at: i at: j))]].
                sum := sum * beta.
                j to: 4 do:[:i|
                        x at: i put:((x at: i) + (sum * (self at: i at: j)))].
        ].
        "Now calculate result"
        4 to: 1 by: -1 do:[:i|
                i+1 to: 4 do:[:j|
                        x at: i put: ((x at: i) - ((x at: j) * (self at: i at: j))) ].
                x at: i put: ((x at: i) / (d at: i))].
        ^B3DVector4 x: (x at: 1) y: (x at: 2) z: (x at: 3) w: (x at: 4)
! !

!B3DMatrix4x4 methodsFor: 'solving' stamp: 'ar 6/23/2002 14:28'!
solve3x3: aVector
        "Solve a 3x3 system of linear equations. Assume that all the a[4,x] and a[x,4] are zero.
        NOTE: This is a hack, but it's the fastest way for now."
        | m |
        m := self clone.
        m a44: 1. "need this for inversion"
        m := m inplaceHouseHolderInvert.
        m ifNil:[^nil].
        ^m localDirToGlobal: aVector.! !

!B3DMatrix4x4 methodsFor: 'solving' stamp: 'ar 2/1/1999 21:52'!
solve: aVector

        ^self clone inplaceHouseHolderTransform: aVector
        "or:
        ^self clone inplaceDecomposeLU solveLU: aVector
        "! !

!B3DMatrix4x4 methodsFor: 'solving'!
solveLU: aVector
        "Given a decomposed matrix using gaussian elimination solve the linear equations."
        | x v |
        v := Array with: aVector x with: aVector y with: aVector z with: aVector w.
        "L first"
        1 to: 4 do:[:i| "Top to bottom"
                x := 0.0.
                1 to: i-1 do:[:j|
                        "From left to right w/o diagonal element"
                        x := x + ((v at: j) * (self at: i at: j))].
                "No need to divide by the diagonal element - this is always 1.0 in L"
                v at: i put: (v at: i) - x].
        "Now U"
        4 to: 1 by: -1 do:[:i| "Bottom to top"
                x := 0.0.
                4 to: i+1 by: -1 do:[:j|
                        "From right to left w/o diagonal element"
                        x := x + ((v at: j) * (self at: i at: j))].
                "Divide by diagonal element"
                v at: i put: (v at: i) - x / (self at: i at: i)].
        ^B3DVector4 x: (v at: 1) y: (v at: 2) z: (v at: 3) w: (v at: 4)
! !


!B3DMatrix4x4 methodsFor: 'testing' stamp: 'ar 2/1/1999 21:54'!
isIdentity
        ^self = B3DIdentityMatrix! !

!B3DMatrix4x4 methodsFor: 'testing' stamp: 'ar 2/1/1999 21:54'!
isZero
        ^self = B3DZeroMatrix! !


!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'atg 10/13/2005 10:04'!
composeWith: aB3DMatrix4x4
        " returns X = parameter * self "
        | result |
        result _ self class new.
        self
                privateTransformMatrix: self
                with: aB3DMatrix4x4
                into: result.
        ^ result! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'atg 10/13/2005 18:35'!
composeWith: m2 times: nTimes
        "Perform a 4x4 matrix exponentiation and multiplication."
        | result |
        result _ self.
        nTimes negative
                ifTrue: [self halt].
        nTimes >= 2
                ifTrue: [result _ result
                                                composeWith: (m2 composeWith: m2)
                                                times: nTimes // 2].
        nTimes \\ 2 = 1
                ifTrue: [result multiplyAndDiscard: m2].
        ^ result! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'ar 2/15/1999 23:56'!
composedWithGlobal: aB3DMatrix4x4
        | result |
        result _ self class new.
        self privateTransformMatrix: aB3DMatrix4x4 with: self into: result.
        ^result! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'ar 5/21/2000 16:34'!
inverseTransformation
        "Return the inverse matrix of the receiver."
        ^self clone inplaceHouseHolderInvert.! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'atg 10/18/2005 19:21'!
localDirToGlobal: aVector
        "Multiply direction vector with the receiver"
        | x y z |
        <primitive: 'b3dTransformDirection' module:'Squeak3D'>
        x _ aVector x.
        y _ aVector y.
        z _ aVector z.
        ^ B3DVector3
                x: x * self a11 + (y * self a12) + (z * self a13)
                y: x * self a21 + (y * self a22) + (z * self a23)
                z: x * self a31 + (y * self a32) + (z * self a33)! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'ar 9/18/2002 17:30'!
localPointToGlobal: aVector
        "Multiply aVector (temporarily converted to 4D) with the receiver"
        | x y z rx ry rz rw |
        <primitive: 'b3dTransformPoint' module: 'Squeak3D'>

        x := aVector x.
        y := aVector y.
        z := aVector z.

        rx := (x * self a11) + (y * self a12) + (z * self a13) + self a14.
        ry := (x * self a21) + (y * self a22) + (z * self a23) + self a24.
        rz := (x * self a31) + (y * self a32) + (z * self a33) + self a34.
        rw := (x * self a41) + (y * self a42) + (z * self a43) + self a44.

        ^B3DVector3 x:(rx/rw) y: (ry/rw) z: (rz/rw)! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'atg 10/11/2005 01:09'!
multiplyAndDiscard: aB3DMatrix4x4
        "derived from 'composedWithLocal'"
        self
                privateTransformMatrix: self
                with: aB3DMatrix4x4
                into: self! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'das 11/9/2004 17:14'!
normalize

        self column1: (self column2 cross: self column3) normalized.
        self column2: (self column3 cross: self column1) normalized.
        self column3: (self column1 cross: self column2) normalized.! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'ar 9/18/2002 17:30'!
orthoNormInverse
        | m x y z rx ry rz |
        <primitive: 'b3dOrthoNormInverseMatrix' module: 'Squeak3D'>
        m := self clone.
        "transpose upper 3x3 matrix"
        m a11: self a11; a12: self a21; a13: self a31.
        m a21: self a12; a22: self a22; a23: self a32.
        m a31: self a13; a32: self a23; a33: self a33.
        "Compute inverse translation vector"
        x := self a14.
        y := self a24.
        z := self a34.
        rx := (x * m a11) + (y * m a12) + (z * m a13).
        ry := (x * m a21) + (y * m a22) + (z * m a23).
        rz := (x * m a31) + (y * m a32) + (z * m a33).

        m a14: 0.0-rx; a24: 0.0-ry; a34: 0.0-rz.
        ^m
" Used to be:
        m _ self clone.
        v _ m translation.
        m translation: B3DVector3 zero.
        m _ m transposed.
        v _ (m localPointToGlobal: v) negated.
        m translation: v.
        ^ m.
"! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'atg 10/18/2005 19:12'!
quickTransformV3ArrayFrom: srcArray to: dstArray
        "Transform the 3 element vertices from srcArray to dstArray.  
       
        ASSUMPTION: a41 = a42 = a43 = 0.0 and a44 = 1.0"
        | a11 a12 a13 a14 a21 a22 a23 a24 a31 a32 a33 a34  |
        self flag: #b3dPrimitive.
        a11 _ self a11.
        a12 _ self a12.
        a13 _ self a13.
        a14 _ self a14.
        a21 _ self a21.
        a22 _ self a22.
        a23 _ self a23.
        a24 _ self a24.
        a31 _ self a31.
        a32 _ self a32.
        a33 _ self a33.
        a34 _ self a34.
        1
                to: srcArray size
                do: [:i |
                        | x y z index |
                        index _ i - 1 * 3.
                        x _ srcArray floatAt: index + 1.
                        y _ srcArray floatAt: index + 2.
                        z _ srcArray floatAt: index + 3.
                        dstArray floatAt: index + 1 put: a11 * x + (a12 * y) + (a13 * z) + a14.
                        dstArray floatAt: index + 2 put: a21 * x + (a22 * y) + (a23 * z) + a24.
                        dstArray floatAt: index + 3 put: a31 * x + (a32 * y) + (a33 * z) + a34].
        ^ dstArray! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'atg 10/18/2005 19:23'!
scaleBy: aVector
"equivalent to making a new scaling matrix then doing composeWith: "
        1
                to: 3
                do: [:j | 1
                                to: 4
                                do: [:i |
                                        | index |
                                        index _ i - 1 * 3 + j.
                                        self at: index put: (self at: index)
                                                        * (aVector at: j)]]! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'atg 10/12/2005 21:50'!
translation: aVector
        self
                a14: aVector x;
                a24: aVector y;
                a34: aVector z! !

!B3DMatrix4x4 methodsFor: 'transforming' stamp: 'ar 9/18/2002 17:30'!
transposed
        "Return a transposed copy of the receiver"
        | matrix |
        <primitive: 'b3dTransposeMatrix' module: 'Squeak3D'>
        matrix := self class new.
        matrix
                a11: self a11; a12: self a21; a13: self a31; a14: self a41;
                a21: self a12; a22: self a22; a23: self a32; a24: self a42;
                a31: self a13; a32: self a23; a33: self a33; a34: self a43;
                a41: self a14; a42: self a24; a43: self a34; a44: self a44.
        ^matrix! !


!B3DMatrix4x4 methodsFor: 'private' stamp: 'ar 11/7/2000 14:48'!
privateTransformMatrix: m1 with: m2 into: m3
        "Perform a 4x4 matrix multiplication
                m2 * m1 = m3
        being equal to first transforming points by m2 and then by m1.
        Note that m1 may be identical to m3.
        NOTE: The primitive implementation does NOT return m3 - and so don't we!!"
        | c1 c2 c3 c4 |
        <primitive: 'b3dTransformMatrixWithInto' module:'Squeak3D'>
        m2 == m3 ifTrue:[^self error:'Argument and result matrix identical'].
        c1 _ ((m1 a11 * m2 a11) + (m1 a12 * m2 a21) +
                                (m1 a13 * m2 a31) + (m1 a14 * m2 a41)).
        c2 _ ((m1 a11 * m2 a12) + (m1 a12 * m2 a22) +
                                (m1 a13 * m2 a32) + (m1 a14 * m2 a42)).
        c3 _ ((m1 a11 * m2 a13) + (m1 a12 * m2 a23) +
                                (m1 a13 * m2 a33) + (m1 a14 * m2 a43)).
        c4 _ ((m1 a11 * m2 a14) + (m1 a12 * m2 a24) +
                                (m1 a13 * m2 a34) + (m1 a14 * m2 a44)).

        m3 a11: c1; a12: c2; a13: c3; a14: c4.

        c1 _ ((m1 a21 * m2 a11) + (m1 a22 * m2 a21) +
                                (m1 a23 * m2 a31) + (m1 a24 * m2 a41)).
        c2 _ ((m1 a21 * m2 a12) + (m1 a22 * m2 a22) +
                                (m1 a23 * m2 a32) + (m1 a24 * m2 a42)).
        c3 _ ((m1 a21 * m2 a13) + (m1 a22 * m2 a23) +
                                (m1 a23 * m2 a33) + (m1 a24 * m2 a43)).
        c4 _ ((m1 a21 * m2 a14) + (m1 a22 * m2 a24) +
                                (m1 a23 * m2 a34) + (m1 a24 * m2 a44)).

        m3 a21: c1; a22: c2; a23: c3; a24: c4.

        c1 _ ((m1 a31 * m2 a11) + (m1 a32 * m2 a21) +
                                (m1 a33 * m2 a31) + (m1 a34 * m2 a41)).
        c2 _ ((m1 a31 * m2 a12) + (m1 a32 * m2 a22) +
                                (m1 a33 * m2 a32) + (m1 a34 * m2 a42)).
        c3 _ ((m1 a31 * m2 a13) + (m1 a32 * m2 a23) +
                                (m1 a33 * m2 a33) + (m1 a34 * m2 a43)).
        c4 _ ((m1 a31 * m2 a14) + (m1 a32 * m2 a24) +
                                (m1 a33 * m2 a34) + (m1 a34 * m2 a44)).

        m3 a31: c1; a32: c2; a33: c3; a34: c4.

        c1 _ ((m1 a41 * m2 a11) + (m1 a42 * m2 a21) +
                                (m1 a43 * m2 a31) + (m1 a44 * m2 a41)).
        c2 _ ((m1 a41 * m2 a12) + (m1 a42 * m2 a22) +
                                (m1 a43 * m2 a32) + (m1 a44 * m2 a42)).
        c3 _ ((m1 a41 * m2 a13) + (m1 a42 * m2 a23) +
                                (m1 a43 * m2 a33) + (m1 a44 * m2 a43)).
        c4 _ ((m1 a41 * m2 a14) + (m1 a42 * m2 a24) +
                                (m1 a43 * m2 a34) + (m1 a44 * m2 a44)).

        m3 a41: c1; a42: c2; a43: c3; a44: c4.! !

"-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "!

B3DMatrix4x4 class
        instanceVariableNames: ''!

!B3DMatrix4x4 class methodsFor: 'instance creation'!
identity
        ^self new setIdentity! !

!B3DMatrix4x4 class methodsFor: 'instance creation' stamp: 'ar 2/1/1999 21:25'!
numElements
        ^16! !

!B3DMatrix4x4 class methodsFor: 'instance creation' stamp: 'ar 2/15/1999 23:58'!
rotatedBy: angle around: axis centeredAt: origin
        "Create a matrix rotating points around the given origin using the angle/axis pair"
        | xform |
        xform _ self withOffset: origin negated.
        xform _ xform composedWithGlobal:(B3DRotation angle: angle axis: axis) asMatrix4x4.
        xform _ xform composedWithGlobal: (self withOffset: origin).
        ^xform! !

!B3DMatrix4x4 class methodsFor: 'instance creation' stamp: 'das 5/16/2002 11:12'!
skew: vector

        ^ self new skew: vector.! !

!B3DMatrix4x4 class methodsFor: 'instance creation' stamp: 'das 1/25/2005 21:53'!
up: up at: at

" construct and orthonormal matrix from the up and at vectors."
        ^ self new up: up at: at.! !

!B3DMatrix4x4 class methodsFor: 'instance creation' stamp: 'atg 10/12/2005 21:50'!
withOffset: amount
        ^self identity translation: amount! !

!B3DMatrix4x4 class methodsFor: 'instance creation' stamp: 'ar 5/10/2001 15:27'!
withRotation: angle around: axis
        ^self new rotation: angle around: axis! !

!B3DMatrix4x4 class methodsFor: 'instance creation' stamp: 'ar 5/20/2001 00:12'!
withScale: amount
        ^self identity setScale: amount! !

!B3DMatrix4x4 class methodsFor: 'instance creation'!
zero
        ^self new! !


!B3DMatrix4x4 class methodsFor: 'class initialization' stamp: 'ar 2/1/1999 21:58'!
initialize
        "B3DMatrix4x4 initialize"
        B3DZeroMatrix _ self new.
        B3DIdentityMatrix _ self new.
        B3DIdentityMatrix a11: 1.0; a22: 1.0; a33: 1.0; a44: 1.0.! !


B3DMatrix4x4 initialize!


Reply | Threaded
Open this post in threaded view
|

Re: The grand update stream. -- appologies..

Alan Grimes
I'm very sorry, I didn't mean to send 40k to the list. I frequently
correspond with Mr. Boyce Off-list and was too tired to notice the
return address...


--
Don't let your schoolwork get in the way of your learning.

http://users.rcn.com/alangrimes/

Reply | Threaded
Open this post in threaded view
|

Re: Some subjective requirements for a radically optimistic "Code-Wiki" (was: Re: bugs on mantis: who assigns them ?)

Markus Gälli-3
In reply to this post by timrowledge

On Mar 8, 2006, at 8:36 PM, tim Rowledge wrote:

>
> On 8-Mar-06, at 7:05 AM, Markus Gaelli wrote:
>
>> Hi folks,
>>
>> I am still waiting for a radically optimistic "wiki like"  
>> environment, where anybody (ok, say having at least the status of  
>> an apprentice on Squeak-People...) can change code of the current  
>> golden_and_shared_image anytime, ideally _always_ developing with  
>> it as the base for his (do we have a she on Squeak-People with at  
>> least apprentice status?) daily work.
> Given the number of mistakes even the best of the Master rated  
> people make I'd really  not like to live in a world where code  
> could just be stuffed in by anyone. Shudder.  I mean for goodness  
> sake, I've been doing this continuously for 23 years and still  
> screw up.
23 years of experience and still making mistakes? Tsss. ;-)

The release process for such a "turnaround image"(*) into a stable  
version could still be conservative: Only allow bugfixes in the last  
two weeks before a release or so.
Hundreds of users will take care. So what would be the worst case  
scenario besides Homer Simpson using a turnaround image instead of a  
released one in his nuclear power plant?

Sure, if my image hangs due to some new code somebody on the other  
end of the world just released, I also get...aehm... sad.
Maybe some clever rollback mechanism could be established, otherwise  
I'd say "no risk no fun" is the mantra of the early adapter.

But I guess the people on the other end of the world will think twice  
about doing an unsafe new release for a package, as they have to sign  
it.
Trust the fine crowd of squeak developers and they might even reward  
you by writing tests. People prefer to be proud of their work and not  
embarrassed, so on the average it should be ok. And if not: Fail  
early, fail often. Let's dare it and embarrass ourselves from time to  
time for real - not only here on the mailing list. ;-)

I think as long as nobody has implemented such a "turnaround image"  
together with a viable migration strategy / hybrid strategy to keep  
the current dev-process in sync,
we don't need to go into further details here. I just wanted to throw  
some blue pane idea in - maybe it was no the best time for it right  
now... ;-)
People using Mantis and co. are doing a terrific job! And this  
process seems to be the best we have at the moment.
Please, next time also send a link (again) together with your nice  
motivating words about using mantis.
This will hinder people like me from lifting off into blue air and  
instead make them doing some real pink work. ;-)

Power to the people!

Markus
(*) Turnaround: The faster the wheel spins the more stable it gets.

12