jump to navigation

Release 0.5 February 8, 2010

Posted by asalga in Open Source, Processing.js, WebGL.
add a comment

This marks my 0.5 release for my open source class at Seneca College. I’m collaborating with a few of students from the class to port over Processing to Processing.js which is a JavaScript implementation of the language. Three of us are working with WebGL to kick-start the 3D functions. This blog details some of the things I’ve been up to for this release.

The Plan

blog post , plan details
While we had all done different pieces of 3D separately for a prior release, it was difficult to merge the code. This why we needed to take a step back and create a plan. This was difficult to write as it involved trying to assess all the 3D dependencies and delegate a decent amount of work. I think I succeeded in figuring out which code relies on other code, but I didn’t assign the right amount of work. I’m not sure why I was so off the mark, but I’m glad my professor Dave pointed out that it was likely not enough. It also became quite clear early on when I was very much ahead of schedule.

Git

Something I needed to re-learn for this release was Git. I wrote a blog post about how I came to terms with this tool. I’m now having a lot of fun using it, but it was challenging to get going. I essentially had to sit down for the day to learn the basics by watching video tutorials, reading and experimenting. After starting with a fresh outlook, I managed to turn something I despised to something with which I’m becoming obsessed. I guess that’s a good thing.

3D Helper Functions

uniformi: ticket
uniformf: ticket
uniformMatrix: ticket
vertexAttribPointer: ticket
I knew a few helper functions would be useful to me in box(), and also useful to others once the code is committed. So I wrapped WebGL functions and named them uniformf, uniformi, uniformMatrix and vertexAttribPointer. I already had the code in C3DL, so I copied it, reformatted it, removed C3DL specific code, and formatted it for Processing.js.

PMatrix3D

Ticket
My progress suffered a lot because I had to rewrite parts of this huge class. We already had a student write it, but we didn’t have a test, which meant I needed to write those. This was not in the least bit fun, but very necessary. I also had to make a few changes to the class. It was within the Processing scope, which had to be changed. I had trouble getting some functions to work, such as mult(), so I had to rewrite those. This class took a considerable amount of time to rewrite and test, but now that it’s going into the repository, it will be available for others to update, modify, fix, optimize, etc.

Box Outlines

Ticket
Sometime during all this coding, I needed to take a break. I thought it would be fun to figure out the vertices needed to render the outline of a cube. We already had the vertices for the solid cube exported from Blender, but drawing those with the lines mode does not render a proper outline. We needed to get a different set of vertices when drawing with lines. I knew opening Blender and playing around with it would probably take longer than doing it by hand. So I found my Rubik’s cube and imagined it at the origin of a 3D coordinate system. I then plotted out all the vertices manually. To make things easy I decided to work with 1’s. I imagined each corner’s respective x,y and z components were 1 unit away from the origin. Once I had an array of -1 and 1’s, I did a search and replace and replaced them all with 0.5’s to make a unit cube. I then fed them into WebGL’s drawArrays() using the lines drawing mode. Box outlines done! This was a fun exercise and also valuable to the next student who decides to pick up strokeWeight(), noFill() and stroke() since they’ll be looking at this code.

Box

ticket
This was probably the most fun and frustrating piece of code I had to write. We already had the code, but needed to tie it together with variables which the camera() function was setting. I started from scratch, dug through the Processing code and slowly pieced together a function which seems to now work. It was absolutely essential to get this properly working since it would allow other students to work with the rest of the 3D functions.

Size

ticket
This was a small change, I just had to update the code so the script was acquiring a context by passing in ‘experimental-webgl’.

IDE 3D DEMO


It’s been a while since I wrote a demo, so I wanted to write one for this release. I knew we would have camera, perspective and box code working, so I imagined I could have some controls on a page which allow the user to transform a box. I then realized there’s no better way to test and demonstrate box() than to just let the user write the Pjs code! But to do anything interesting, I had to implement rotateX(), rotateY(), rotateZ() and translate(). This took some time as I had to ‘trace’ through the Processing code and figure out what it was doing when those functions were called. I started with hardcoded lines in box() for the transformations and eventually all those lines were stripped out and replaced with calls to rotate and translate in the Pjs script. It took a while, but it wasn’t just necessary for this demo. I was testing to make sure everyone’s code in the future (0.6) would actually work.

Once I finished that, I started working on the actual demo. I had no idea how long it would take to get it to work ‘dynamically’, so I was hesitant, but I tried anyway. I analyzed the Web IDE on the Processing.js web site and wrote my own, very similar page. The page is still a bit buggy, but it mostly works. It also serves as a great way to let the user compare between Processing and Processing.js sketches.

While writing the Web IDE demo, I ran into an interesting bug. I had the page setup with the textarea, the 3D context was acquired, background filled, but no box. I opened the error console and found an obscure exception. I wondered why this was happening. I came up with all sorts of crazy ideas, but nothing made sense, so I ran a search. I was incredibly surprised to find THIS. Well, well, well. Very interesting. This a bug I filed, and I’m sure glad I filed it too. This bug led me to believe there was something funky with the size() call in Pjs and the HTML canvas width and height. I knew this because I get that exception when the dimensions in size() and the canvas dimensions differ. After a bit of thinking I decided to remove the canvas width and height from the inline CSS and replace it with regular attributes, and yes it worked. That was like time travel debugging.

Wiki Update

I also update my wiki page which includes tickets for all the things I’ve been working on.

Box Outline, Camera, PMatrix3D, Translate, Scale, etc… February 4, 2010

Posted by asalga in Open Source.
add a comment

I’m in the process of trying to tie together a bunch of functions and code and make them all work. I have vertices of box outlines, Mickael’s camera code, Anna’s box function, the PMatrix3D object and a matrices all over the place. So far I’m making progress. I had to dig through a bunch of processing code to see what exactly the Java version of the language is doing that was making my results so different. A few things I figured out was where they were transposing their matrices, I also found out they are indeed flipping the Y axis. My kludge was removed and replaced with a scale(1,-1,1), just the way they do it. I also had to modify the camera code so it looks more like their code. In addition, I found that their box outline vertices do indeed create a unit cube, so I scaled mine by 0.5.

After finding all these out, my outline code, box scaling code and camera code is starting to make some sense. Here’s a screenshot of me trying to make both Processing and Processing.js identical.

This demo is a mess. For some reason, in Pjs I have to specifically render the box in draw, otherwise it doesn’t render at all. I also have to do a literal translation in Pjs within the box function because adding a p.translate in the Pjs scope is somehow recursively calling another translate function. After it rendered, I counted the pixels and our version’s box is slightly larger, by 2 pixels. Since the box is so far away it might have a big different later, so I’ll have to look into that. But might look like old news compare to other stuff we have. But one main different is we’re now using the Edward’s refactored PMatrix3D object.

I’m happy that even though I have to do a literal translation in the box() code, it’s much clearer than multiplying Y by -1 all over the place. Once I can rip out this translation, we can start playing around with moving the box around. I’m also working on scaling the box if the user sends in arguments. In Processing, they just scale each vertex one by one. This is a bit wasteful, especially since we would have to call bufferData() each time box() was called. It would be more efficient to just apply a scale matrix. The problem is I have to call preApply() on the PMatrix3D instead of apply (Matrix A * Matrix B != Matrix B * Matrix A). I’m still unsure why I have to do this, and it’s been driving me crazy. But anyway, I’m pretty glad that the Pjs version is getting closer and closer to Processing. Here I’m translating and scaling (right now literally), but it shows up in the correct place!

I’ll be committing all this stuff to my experimental branch in Github by the end of the week.

Git: The Crazy Lightsaw February 3, 2010

Posted by asalga in Open Source.
1 comment so far

Last semester in my open source class we used Git to manage our code patches. Learning Git was a frustrating experience, mostly because I approached the tool as if it was SVN. When using SVN, it’s hard to really screw something up. But Git is different.

This semester we’re again using Git. I knew the tool wasn’t going to change between semesters, so I knew I had to change my attitude. I decided to take it slow. No more throwing in commands and seeing if they work. Not this time. I recreated my repository and took it nice and slow. Before writing anything into the console, I first researched what it really does and how it works. I looked at examples and tried to piece everything together. I can say confidently that using Git has been a much more pleasant experience this time around. Actually, I’m beginning to start appreciating the system. It’s becoming more transparent and I think that should be the main goal of version control tools. I can now type commands and everything seems to just work like magic! cooool.

I learned Git isn’t SVN. The way I see it, SVN is like a dull hacksaw and Git, well that’s like some crazy ultra-powered lightsaber-chainsaw. If you know what you’re doing, you can do some pretty cool things (I dunno, slice through blast shields?). If you don’t handle the tool properly, it’s going to hurt. So far I’ve only been using basic functions-the most complex being creating branches. So I’m excited to see what else Git has to offer.

Messing Around

You know you really like something when you start playing around with it just for fun : ) I opened the config file in the .git directory and started messing around with the colors.

By the time I’m done Git’s output will look like…what? IRC?

Ancient V.S. Contemporary Comedies January 28, 2010

Posted by asalga in Reading.
add a comment

Something I noticed while reading Lysistrata is that it was actually funny, and I enjoyed it quite a bit. Maybe it’s my taste, but I find contemporary comedies (movies) are just terrible. All the comedies my friends like, I hardly find humorous. Which makes it interesting how a play written a few thousand years ago can stay timeless and still make someone laugh. Maybe there are some good contemporary comedic plays around. I’ll have to look into this.

3D Processing.js Development Deadlock January 28, 2010

Posted by asalga in Open Source, Processing.js.
add a comment

A few days ago I blogged about the problem of adding 3D to the Processing.js library. After I wrote the blog, I knew I needed to dig a bit further. A blog was okay, but I needed more. So I began the terribly confusing task of trying to categorize functions into releases and delegate the work so each developer doesn’t rely on other concurrently developing code. After I had something workable on paper, I posted it on our wiki page so it can be reviewed by the rest of the Processing.js team.

Deadlock

The main issue is there’s a bit of a deadlock for release 0.5. Anna is responsible for the box() function which renders a box in the scene. That function depends on Mickael’s camera() and perspective() functions, which are difficult to test without rendering something! I think to begin with, we’ll all have to work together (as in the same room) to figure all this out. Hopefully this week’s Processing.js team meeting will clear up some things.

Preliminary Plan For 3D in Processing.js January 26, 2010

Posted by asalga in Open Source, Processing.js.
2 comments

I was talking to Dave Humphrey on IRC about the state of the tickets which involve adding 3D functionality to the Processing.js library. And well, things are a bit hectic right now. We have a slew of tickets in lighthouse which need review, 3D dependencies haven’t been identified. We have code for drawing spheres and boxes, but no camera or perspective code checked in. All this needs some serious attention. What we need to do is identify what the dependencies are and focus our energy on getting those tickets checked in. Once that’s done, we can begin working on getting our other tickets ready for review.

Our next release is happening on the 5th. By that time we need to get a whole bunch of things ready for super review. The question is which parts? I have identified the blocking code here.

PMatrix3D

Let’s start with this object. This isn’t used by Processing.js scripts directly. It’s an internal structure for us developers working on the Pjs library. Once we have parts of it written we can all benefit from the tested code it provides. The problem is it’s huge. It has functions to scale, rotate, translate, skew, invert, etc. Luckily for us, since it isn’t exposed to users writing sketches, we can omit the functions of the class which aren’t mandatory and we can focus on the core elements, which are only a handful of functions. I believe we should concentrate on those, get the basics in then worry about the rest. I’ve tried to limit the code to the absolute minimum since the more function we add, the more tests are required. The more tests we need, the further back the release gets pushed. I want a substantial amount to get pushed, but no more than necessary. So these are the functions which need attention:

set() – Sets the matrix
mult() – Multiplies a vector by a matrix
apply() – Multiplies the matrix with another matrix

Yes, this is a very short list and I’m leaving out a whole bunch of functions. I’m even leaving out trivial code like transpose and reset (which sets the matrix to an identity matrix). These will need to get done manually until we have a test. Without a test, I don’t want to put it up for super review. We can still do translations, rotations and whatever by specifying our own matrices and calling apply(), so it still provides enough functionality to do some work.

On one hand, I don’t want to stunt the development of adding 3D to Processing.js, but I also don’t want us to push buggy code. That could leave someone scratching their head for hours because they think our code works when in fact it has a bug. I’m drawing the line at these functions. If someone notices we need another one, we’ll need a test for it. The code for these have already been written, now we have to delegate the work of writing the tests.
TODO:

  • Write tests for set(), mult() and apply()

camera()

camera() ticket

The camera() function places a virtual camera in the scene. It describes where the camera is, where it’s pointing and it’s ‘up’ direction. By default, this is called when a user creates a 3D scene, this makes the implementation an absolute must and of high dependency. Even if we don’t have any objects rendered, we need this guy landed.

Luckily Mickael Medel has already written the JavaScript implementation of camera(), it just requires fixing, debugging and a test. While I was reviewing the code, I saw it depends on PVector, but that’s fine since PVector has already been checked in. Nice.
TODO:

  • Fix bugs
  • Write a test for camera()

perspective()

perspective() ticket

Perspective creates a viewing volume. When objects are placed ‘inside’ this volume, they appear as they do in real life. That is, when they are farther from the camera, they appear smaller. The code is written, we just need to fix, debug and write a test. Like camera(), this function is a must since it is called by default (I even checked the Processing code to make absolute sure). Perspective in turn calls frustum().
TODO:

  • Fix bugs
  • Write a test for perspective()

frustum()

frustum() ticket

This allows you to create the viewing volume directly with more control over the final ’shape’ of the volume compared to perspective(). Not only is this called by perspective, but users can call it directly. So this is also of high priority. Fortunately for us, the code is quite simple and standard. Writing a test for this should be fairly straightforward.

TODO:

  • Write a test for frustum()

Plan Alterations

In a few days we’ll be having our weekly Processing.js meeting. At that time we can add, remove, and alter the details of this plan. Once we have these elements in the code, the user will be able to call size() (which has already landed), call camera() and set the viewing volume with either perspective() or frustum(). The user can also change the background color (also landed) and ….that’s about it :s If we get ahead of schedule, I’ll plow on and get box() or rect() ready for review. It seems like we are taking a step backwards, but I believe this is a step in the right direction.

My Processing.js Release 0.4 January 25, 2010

Posted by asalga in JavaScript, Open Source, Processing.js.
add a comment

I’m working on parts of the Processing.js library for my open source class. This marks my 0.4 release.

For this release, students in the class weren’t actually supposed to write any code. This is because we have to sort through a large number of tickets in lighthouse, which need review. The plan was that the students would do some peer or first level review. If it passed that review, we could submit the bugs for super review so the code lands in the Processing.js branch. I browsed the tickets which needed review and assigned a few to myself. I have never officially reviewed another developer’s code, so I was interested in how it would work.

I started with a quick search on code review. Some of the more valuable links I found were:
Code Review Checklist
Mozilla – How to Submit a Patch

Before starting my reviews, I compiled a short checklist of things I’ll try to enforce. Not all of them apply, but I was just getting an idea of what things to look out for in the future.

  • Does the code work?
  • Does the code have tests?
  • Does it break regression tests?
  • Is the code properly documented?
  • Does the code introduce security concerns?
  • Are function and variable names congruent with the codebase?
  • Is the indent/brace/spacing style adhered to?
  • Does the code have a performance impact?
  • Can the code be simplified?
  • Can the code be more efficient?

I ended up assigning many more tickets to myself than I was able to review. I didn’t finish my reviews partly because I got stuck trying to fix the bugs present in the code I was reviewing. I know when submitting a patch to a large open source project there’s no way someone reviewing your code will start to debug it for you. But since we’re a fairly small team, I figured I could help out. Here are the tickets I did manage to review.

camera()

Lighthouse Ticket: camera()

Testing this one took a while, but I eventually managed to make it run. One of the problems is there was this line:

if( arguments.length = 0 )

It actually took me a while to catch it and I think many developers from time to time still make this mistake. I recall reading a textbook (probably Code Complete) which mentioned that if you find yourself making this mistake often, change your style to this:

if( 0 == arguments.length )

Anytime you try to use only one equal sign, you’ll get an error telling you zero isn’t an lvalue. That is, it can’t be on the left side of an assignment. And since we’re using JavaScript, we might as well add another equals sign.

if( 0 === arguments.length )

You can see the rest of my comments on camera() in the camera lighthouse ticket.

join()

Lighthouse ticket: join()
My additional tests: join() tests

Alex wrote a test for his implementation of join(). I wanted write a few more tests before I submitted the ticket for super review. I started writing them, but soon found that my tests were breaking the library. After some research I found that nf() was not returning the correct values. So I had to comment out those from my tests which used nf(). Once we have nf() working, I can update my tests to test for joining int and float arrays. Other than that, the code seems to pass my tests. I marked it for super review and moved on.

P3DMatrixStack object

Lighthouse Ticket: P3DMatrixStack

I got stuck on this one. The logic to multiply the matrices looked deceptively correct and simple. However the matrices that I was testing weren’t being properly multiplied. After finally just throwing in some debug print statements, I saw what was actually happening. The logic in fact was not correct. Whenever you see a matrix multiplication in nested for loops, keep in mind matrix multiplication is O(n3). If it doesn’t look like O(n3), it’s probably wrong (however there are some faster implementations). That is, there should be a bunch of logic in the last code block or there should be a third for loop.

frustum()

Lighthouse ticket: frustum()

This code looks fine, it’s the same logic you can find all over the Web, but we still need a test. So I marked the ticket as “needs work”.

Remnants & More Tests Required

A lot of the other lighthouse tickets I assigned myself to review don’t have tests. Since some of the students who worked on them are no longer in the class, I’ll have to undertake writing tests for those bugs. So here are the bugs I still need to review:

Simplifying the Interface January 23, 2010

Posted by asalga in C3DL, JavaScript, Open Source.
add a comment

Something I need to do is simplify the C3DL interface. When approaching such tasks, one method I found extremely useful was to analyze the code in terms of the interface, or that is from the user’s perspective. To do this I first created a basic demo of a spinning cube by writing the necessary HTML and JavaScript files. As for the HTML, it will need to be something like this:
(I emphasized the code which potentially could be changed)

<html>
  <head>
    <title>Cavas3D Demo</title>
    <script>var SCRIPT_PATH = '../../canvas3dapi/'</script>
    <script src="../../canvas3dapi/c3dapi.js">
    <script src="basic_demo.js"></script>
  </head>

  <body>
    <canvas id="demo" width="500" height="500"></canvas>
  </body>

</html>

It would be great if this could be simplified to something like this:

<html>

  <head>
    <title>Cavas3D Demo</title>
    <script src="../../canvas3dapi/c3dapi.js">
  </head>

  <body>
    <canvas datasrc="basic_demo.js" width="500" height="500">
    </canvas>
  </body>

</html>

I removed the somewhat unintuitive SCRIPT_PATH variable and moved the basic_demo.js resource into the canvas tag making it more obvious which .js file is associated to which canvas. These changes haven’t actually been made, I’m just playing with possible changes, brainstorming which parts might be able to be modified.

Now, very few changes were made here and it will probably require a significant amount of effort to make it work. But this work is justified by the fact that the user’s experience and first impression will be more positive. If the user has to spend more than a few minutes trying to get a simple example to render, they’ll probably look for alternatives.

Let’s see how the JavaScript could be changed. Right now, you need to write something like this:
(Again, I emphasized the code which potentially could be changed)

c3dl.addModel('cube.dae');
c3dl.addMainCallBack(mainDemo, 'demo');

function mainDemo(canvasName)
{
  var scn = new c3dl.Scene();
  scn.setCanvasTag(canvasName);
  var renderer = new c3dl.OpenGLES20();
  scn.setRenderer(renderer);
  scn.init();

  var cam = new c3dl.FreeCamera();
  cam.setPosition([0,0,50]);
  cam.setLookAtPoint([0,0,-1]);

  var cube = new c3dl.Collada();
  cube.init('cube.dae');
  cube.setAngularVel([0.001,0.001,0.0]);

  scn.addObjectToScene(cube);
  scn.setCamera(cam);
  scn.startScene();
}

Some changes I had in mind involved getting rid of the global c3dl.addModel() and c3dl.addMainCallback() calls and changing OpenGLES20 to just Renderer. The Renderer is an interesting problem. When WebGL started out as Canvas3D, we called the renderer OpenGLES11, then later it became OpenGLES20 and now it could probably be WebGL. Considering how much it has changed and will change, we’ll have to invest some time to make this stop. One simple solution is to abstract the renderer.

For example, if we change OpenGLES20 class to Renderer, the user will no longer need to be concerned what underlying rendering method is used. If a visitor loads the user’s demo, but visitor’s browser doesn’t support WebGL (i.e. it’s I.E.), the demo still loads. This of course only works if we accommodate for this case. So if the browser is IE, we use DirectX. If the browser supports WebGL, we use that. The end result is the user’s page will create the appropriate renderer without them needing to worry about the user’s browser. So let’s look at what lines changed:

function mainDemo(canvasName)
{
  var scn = new c3dl.Scene();
  var renderer = new c3dl.Renderer();
  scn.init(renderer);

  var cam = new c3dl.FreeCamera();
  cam.setPosition([0,0,50]);
  cam.setLookAtPoint([0,0,-1]);

  var cube = new c3dl.Collada();
  cube.init('cube.dae');
  cube.setAngularVel([0.001,0.001,0.001]);

  scn.addObjectToScene(cube);
  scn.setCamera(cam);
  scn.startScene();
}

In terms of the lines trimmed, I’m not certain how much of it is viable. The reason some of the seemingly redundant code is required was because I couldn’t devise any alternative at the time. Looking at it from a different perspective, I should be able to come up with something. In the end we’ll have an interface which is more flexible, easier to understand and of course simple.

WebGL Processing.js Reftests January 20, 2010

Posted by asalga in Open Source, Processing.js, WebGL.
4 comments

I’m working on adding 3D functionality to the Processing.js library. Since any Processing.js scripts should render exactly the same as identical Processing scripts, it would make sense to use reference tests. This will ensure all my WebGL code is rendering objects where they should be and with correct lighting. I’m using Minefield to run the tests since it has reftest functionality along with support for WebGL to render the 3D objects.

HTML Vs. PNG

At first I had to play around with Minefield’s configuration to get reftests working. I was able to correctly compare two identical basic HTML files. Once I got over that hurdle, I went to the next one. I knew I would need to compare screenshots from the PDE environment against whatever is rendered in the web page using PJS. To make things simple, I started to experiment with very basic (no Processing) HTML vs. PNG reftest. I had a string rendered in an HTML page and a rasterized string in a PNG file. I ran the tests, but Minefield kept telling me some arbitrary number of pixels differed between the web page and the image.

Script Vs. Script

Not finding much help on the Web, I thought it might be a better decision to simply create a Processing script in the PDE, export it to HTML as my first compare file. Then use that same Processing script to create a PJS test in another web page as the second compare file. Finally I could ask Minefield to render and compare the two. It seemed like a good idea at the time. I was getting awfully tired of taking screenshots.

My Processing test case was as simple as it could get:

size(100,100);
background(0);

I threw this in the PDE, exported it, cut out all the unnecessary CSS and got a plain black canvas rendered in a Web page. Before creating a real PJS script, I decided to first test with a page which just had an tag with the same black square. When I went back to my shell and ran the tests, they failed. Now, when reftests are executed, the browser opens a window, renders the page and closes it. This happens pretty quickly, and I saw a bunch of blue text, which was very odd. It should have been drawing the black square. It turns out I opened the exported Processing file in my default browser earlier (that’s why it worked) and now I was running the reftests in Minefield and I was getting this:

Get the latest Java Plug-in here.

That’s when I remembered Minefield doesn’t have a compatible JRE, at least for OSX. This means there’s no way I can load the applet in Minefield to properly test. Of course I can go back to an older version of Firefox which does have Java, but that won’t have support for WebGL. As much as this sucks, the situation is a bit funny.

? Vs. ?

Okay, what can I do now? I could go back and figure out how to make HTML vs. PNG comparisons work. I’m not keen on doing this because grabbing screenshots is extremely tedious. The solution is also very inflexible. If I change my PJS test script, I need to grab yet another screenshot as opposed to a simple export in PDE and trim away unneeded CSS. Another solution could involve running the reftests on another platform such as Windows or Linux. Perhaps they have Java runtimes available. Hmm… Are reftests powerful enough to have a page open with one version of Firefox and another page with Minefield? I doubt it. Maybe there is some other technique of getting this to work. I’ll bring it up in this week’s Processing.js conference call. Hopefully I’ll get some suggestions.

Offering Alms January 16, 2010

Posted by asalga in Random.
add a comment

I always found it a bit awkward offering money or food to the needy if they didn’t ask. Will they be insulted? Will they reject my alms? That would be embarrassing. I was feeling terrible for tragedy that struck Haiti, but didn’t see any way I could help. So I decided to do something to help someone closer in proximity. I saw a homeless man and I forced myself to risk the embarrassment of rejection and offered food I had on me. I asked him if he’d like it, and he accepted. I felt like I helped someone out. “Be the change you want to see in the world“. I want to see more people helping one another out, so I tried and did the least I could. Then I was told the homeless guy was a retired law professor. Nice.

My girlfriend sorted our laundry a few days ago since we’ll be washing everything on the weekend. In the process, she gathered some old clothes and set them aside for donations to Value Village. When we arrived home, I realized there is probably a program in place to send donations to Haiti, so we agreed to send the bags of clothing there instead.