Sunday, December 30, 2012

WebGL: creating a plane


function initQuadBuffer(){
triangleVertexPositionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
    var vertices = initPlaneArray(1, 1, 10, 10);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    triangleVertexPositionBuffer.itemSize = 3; // (x, y, z)
    triangleVertexPositionBuffer.numItems = 6*10*10; // number of vertices
}
function initPlaneArray(w, h, rows, cols){
var vertices = new Array();
var dx = w / cols;
var dy = h / rows;
var idx = 0;
var x = 0, y = 0;
for(var k = 0; k < rows; k++){
x = 0;
for(var i = 0; i<cols; i++){

vertices[idx] = x;  vertices[idx+1] = y;  vertices[idx+2] = 0.0;
vertices[idx+3] = x+dx;  vertices[idx+4] = y+dy;  vertices[idx+5] = 0.0;
vertices[idx+6] = x;  vertices[idx+7] = y+dy;  vertices[idx+8] = 0.0;

vertices[idx+9] = x;  vertices[idx+10] = y;  vertices[idx+11] = 0.0;
vertices[idx+12] = x+dx;  vertices[idx+13] = y;  vertices[idx+14] = 0.0;
vertices[idx+15] = x+dx;  vertices[idx+16] = y+dy;  vertices[idx+17] = 0.0;

idx += 18;
x += dx;
}
y += dy;
}

return vertices;
}

Friday, December 28, 2012

Mac OS X: pyglet


installed pyglet
tried a simple app and run, get the following error:

OSError: dlopen(/System/Library/Frameworks/QuickTime.framework/QuickTime, 6): no suitable image found.  Did find:
 /System/Library/Frameworks/QuickTime.framework/QuickTime: mach-o, but wrong architecture
 /System/Library/Frameworks/QuickTime.framework/QuickTime: mach-o, but wrong architecture

found a link: https://groups.google.com/forum/?fromgroups=#!topic/pyglet-users/mvvIo7NotBo

so run the command in Terminal: "defaults write com.apple.versioner.python Prefer-32-Bit -bool yes"
to set python to run in 32 bit mode
and then compile app again. no problem.

Monday, December 10, 2012

FlasCC: 1st experience

1) Download and extract FlasCC zip
2) try making the Hello sample. eg.: ..\..\sdk\usr\bin\make FLASCC="../../sdk" FLEX="../../../flex_sdk_4.6"
3) error
"-------- Sample 1 --------

First let's compile it as a projector:
"../../sdk/usr/bin/gcc" -Werror -Wno-write-strings -Wno-trigraphs hello.c -o hel
lo.exe
cc1: error in backend: Failed to run /cygdrive/c/Program Files/Git/bin/which wit
h args: java
Error:
/cygdrive/c/Program Files/Git/bin/which: line 7: $'\r': command not found

make: *** [T01] Error 1"

4) use dosunix on the "which" in Git\bin

5) then run again, another error
"LLVM ERROR: Error: Unable to launch the Java Virtual Machine.
This usually means you have a 32bit JVM installed or have set your Java heap siz
e too large.
Try lowering the Java heap size by passing "-jvmopt=-Xmx1G" to gcc/g++.
Stack dump: [blah blah ....]

make: *** [T01] Error 1"

6) added '-jvmopt="-Xmx1G"' to Makefile
"T01: check
@echo "-------- Sample 1 --------"
@echo && echo "First let's compile it as a projector:"
"$(FLASCC)/usr/bin/gcc" $(BASE_CFLAGS) -jvmopt="-Xmx1G" hello.c -o hello.exe

@echo && echo "Now lets compile it as a SWF:"
"$(FLASCC)/usr/bin/gcc" $(BASE_CFLAGS) -jvmopt="-Xmx1G" hello.c -emit-swf -swf-size=200x200 -o hello.swf

include ../Makefile.common

clean:
rm -f hello.swf hello *.bc *.exe"

7) finally no error and EXE and SWF generated.

Sunday, December 02, 2012

WebGL start

Reference: http://learningwebgl.com/blog/?p=28

download js matrix library: https://github.com/toji/gl-matrix/downloads

write the shader source code in a <script></script> tags

<script id="shader-fs" type="x-shader/x-fragment">
  precision mediump float;

  void main(void) {
    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
  }
</script>

<script id="shader-vs" type="x-shader/x-vertex">
  attribute vec3 aVertexPosition;

  uniform mat4 uMVMatrix;
  uniform mat4 uPMatrix;

  void main(void) {
    gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
  }
</script>

variables needed in the javascript code

var triangleVertexPositionBuffer;
var squareVertexPositionBuffer;
var gl;
var shaderProgram;
var mvMatrix = mat4.create();
var pMatrix = mat4.create();

function webGLStart() {
    var canvas = document.getElementById("mycanvas");
    initGL(canvas);
    initShaders();
    initBuffers();

    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.enable(gl.DEPTH_TEST);

    drawScene();
}

function initGL(canvas) {
  try {
    gl = canvas.getContext("experimental-webgl");
    gl.viewportWidth = canvas.width;
    gl.viewportHeight = canvas.height;
  } catch(e) {
  }
  if (!gl) {
    alert("Could not initialise WebGL, sorry :-(");
  }
}

function initShaders() {
  var fragmentShader = getShader(gl, "shader-fs");
  var vertexShader = getShader(gl, "shader-vs");

  shaderProgram = gl.createProgram();
  gl.attachShader(shaderProgram, vertexShader);
  gl.attachShader(shaderProgram, fragmentShader);
  gl.linkProgram(shaderProgram);

  if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
    alert("Could not initialise shaders");
  }

  gl.useProgram(shaderProgram);
  
  shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
  gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
  
  shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
  shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
}
function getShader(gl, id) {
    var shaderScript = document.getElementById(id);
    if (!shaderScript) {
        return null;
    }

    var str = "";
    var k = shaderScript.firstChild;
    while (k) {
        if (k.nodeType == 3)
            str += k.textContent;
        k = k.nextSibling;
    }

    var shader;
    if (shaderScript.type == "x-shader/x-fragment") {
        shader = gl.createShader(gl.FRAGMENT_SHADER);
    } else if (shaderScript.type == "x-shader/x-vertex") {
        shader = gl.createShader(gl.VERTEX_SHADER);
    } else {
        return null;
    }

    gl.shaderSource(shader, str);
    gl.compileShader(shader);

    if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
        alert(gl.getShaderInfoLog(shader));
        return null;
    }

    return shader;
}

function initBuffers() {
    triangleVertexPositionBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
    var vertices = [
                    0.0,  1.0,  0.0,
                   -1.0, -1.0,  0.0,
                    1.0, -1.0,  0.0
               ];
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
    triangleVertexPositionBuffer.itemSize = 3; // number of component to represent a vertex = 3; (x, y, z)
    triangleVertexPositionBuffer.numItems = 3; // number of vertices
}

function drawScene() {
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight); gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix); mat4.identity(mvMatrix); mat4.translate(mvMatrix, [0, 0.0, -5.0]); gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);
}

function setMatrixUniforms() {
    gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);
    gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);
}

HTML
<body onload="webGLStart()">
<canvas id="mycanvas" style="border: none;" width="500" height="500"></canvas>
</body>


Saturday, December 01, 2012

PyQT - OpenGL - Timer


import sys
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtOpenGL import *
from PyQt4 import uic

class MyOGLWidget(QGLWidget):
    def __init__(self, parent=None):      
        QGLWidget.__init__(self, parent)
        self.spin = 0
             

    def initializeGL(self):
        print "init GL"
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glShadeModel (GL_FLAT)
        self.timer = QTimer(self)
        self.timer.timeout.connect(self.spinDisplay)
        self.timer.start(40)
        print self.timer
     

    def resizeGL(self, w, h):
        print "resize: " + str(w ) + " x " +str(h)
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);

    def paintGL(self):
        print "paint GL"
        glClear (GL_COLOR_BUFFER_BIT );
        glPushMatrix()
        glRotatef(self.spin, 0, 0, 1)
        glColor3f (1.0, 1.0, 1.0);
        glRectf(-25.0, -25.0, 25.0, 25.0);
        glPopMatrix()
        glFlush();
     
    def spinDisplay(self):
        # print "spin display"
        self.spin = self.spin + 2
        self.spin = self.spin % 360
        # print self.spin
        #glutSwapBuffers()
        self.updateGL()
   
app = QApplication(sys.argv)
window = MyOGLWidget()
window.resize(300, 300)
window.setWindowTitle("Testing OpenGL in PyQT")
window.show()

sys.exit(app.exec_())


PyQt - OpenGL

install PyOpenGL - http://pyopengl.sourceforge.net/
install QT - http://qt-project.org/downloads
install PyQT- http://www.riverbankcomputing.com/software/pyqt/download
for Mac OS X, install PyQTX - http://sourceforge.net/projects/pyqtx/files/

import sys
from OpenGL.GL import *
from OpenGL.GLU import *
from PyQt4.QtGui import *
from PyQt4.QtOpenGL import *
from PyQt4 import uic

class MyOGLWidget(QGLWidget):
    def __init__(self, parent=None):
        QGLWidget.__init__(self, parent)      
 
    def initializeGL(self):
        print "init GL"
        glClearColor(0.0, 0.0, 0.0, 0.0);
        glShadeModel (GL_FLAT)
 
    def resizeGL(self, w, h):
        print "resize: " + str(w ) + " x " +str(h)
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);
 
    def paintGL(self):
        print "paint GL"
        glClear (GL_COLOR_BUFFER_BIT );
        glColor3f (1.0, 1.0, 1.0);
        glRectf(-25.0, -25.0, 25.0, 25.0);
        glFlush();
     
app = QApplication(sys.argv)
window = MyOGLWidget()
window.resize(300, 300)
window.setWindowTitle("Testing OpenGL in PyQT")
window.show()

sys.exit(app.exec_())



QT designer ui in python PyQT - event


import sys
from PyQt4.QtGui import QApplication, QDialog
from PyQt4 import uic

# a sample event listener
def handle():
    print "clicked"
    # get text in QTextEdit to display in QLabel
    ui.label.setText("hello " + ui.textEdit.toPlainText())

app = QApplication(sys.argv)
window = QDialog()
# dialog.ui is an xml file generated by QT designer
ui = uic.loadUi("dialog.ui")

# set text of QTextEdit
ui.textEdit.setText("hello")
# set text with HTML
ui.textEdit.setHtml("bolditalic")
# connect an event to a listener
ui.pushButton.clicked.connect(handle)

ui.show()

sys.exit(app.exec_())


QT .UI XML

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QDialogButtonBox" name="buttonBox">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>240</y>
     <width>341</width>
     <height>32</height>
    </rect>
   </property>
   <property name="orientation">
    <enum>Qt::Horizontal</enum>
   </property>
   <property name="standardButtons">
    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
   </property>
  </widget>
  <widget class="QLabel" name="label">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>200</width>
     <height>13</height>
    </rect>
   </property>
   <property name="text">
    <string>TextLabel</string>
   </property>
  </widget>
  <widget class="QTextEdit" name="textEdit">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>30</y>
     <width>231</width>
     <height>50</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>110</y>
     <width>75</width>
     <height>23</height>
    </rect>
   </property>
   <property name="text">
    <string>PushButton</string>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>buttonBox</sender>
   <signal>accepted()</signal>
   <receiver>Dialog</receiver>
   <slot>accept()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>248</x>
     <y>254</y>
    </hint>
    <hint type="destinationlabel">
     <x>157</x>
     <y>274</y>
    </hint>
   </hints>
  </connection>
  <connection>
   <sender>buttonBox</sender>
   <signal>rejected()</signal>
   <receiver>Dialog</receiver>
   <slot>reject()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>316</x>
     <y>260</y>
    </hint>
    <hint type="destinationlabel">
     <x>286</x>
     <y>274</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>



Friday, November 30, 2012

Loading QT Designer .ui file in PyQT

Create .ui in QT Designer (QT Creator > New File > QT Form)


import sys
from PyQt4.QtGui import QApplication, QDialog
from PyQt4 import uic

app = QApplication(sys.argv)

# returns a QWidget subclass

# assume that dialog.ui is created from QT designer
ui = uic.loadUi("dialog.ui")
ui.show()

sys.exit(app.exec_())


Thursday, October 18, 2012

C# PInvoke MDA error, stack imbalance

Issue with MDA PInvoke error, stack imbalance. even though had checked to make sure that the parameters match the DLL method signature.

Learnt from Mark that have to add an additional parameter.

[DllImport("somelibrary.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int methodName(string parameter);
 



Sunday, September 30, 2012

Installing Python libraries in Mac OS X

Thanks to the post in http://ashearer.com/blog/2011/xcode/ 
was trying to install Python Imaging Library (PIL), failed. 
basically from the post linked:
'enter the following command line once and the effect will last across multiple builds or installations for the remainder of the terminal session.'

export ARCHFLAGS="-arch i386 -arch x86_64"


Saturday, September 29, 2012

python + socket + xml

made a silly error:
xmldom = xml.dom.minidom.parseString(xml)
xml is a string containing the xml doc.
but its name clashes with the xml.dom.minidom package
xmldom = xml.dom.minidom.parseString(xml_string)

xml processing:
elements = xmldom.getElementsByTagName("mytag")
print elements.length                  # return number of elements
element.getAttribute("myattr")


using multiple line for code. use "\"
eg.: print "this, " + "that, " \
                + "those"

Dictionary
mydictionary = {"mykey":"hehe"}
mydictionary["newkey"] = "hello"       # can be number too
for k, v in mydictionary.iteritems():
   print k + "= " + v
if  "key" in mydictionary:
   print "key exists in dictionary"


Socket client:
import socket
socket = socket(AF_INET, SOCK_STREAM)
socket.connect(("127.0.0.1", 5000))   # address and port
data = socket.recv(4096)              # 4096 bytes buffer


binary data
data = bytearray(socket.recv(4096))
size = (data[3]<<24 | data[2]<<16 | data[1]<<8 | data[0] ) # to 32-bit or 4 byte integer


python imaging (PIL)

all thanks to the link: http://yufu.co/wordpress/?p=15

JPEG decoding from binary data using PIL. Documentation is lacking in official PIL site: http://www.pythonware.com/library/pil/handbook/image.htm

import Image
f = open("myimage.jpg", 'rb')
data = f.read()
im = Image.fromstring('RGB', (640,480), data, 'jpeg', 'RGB', '')



Tuesday, August 28, 2012

Android: Activity, View, onDraw, Canvas

Drawing on canvas overriding onDraw() method
Assuming using RelativeLayout in xml and with id "layout1"


public class SecondActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        //setContentView(new MyView(this));
        RelativeLayout layout = (RelativeLayout)(this.findViewById(R.id.layout1));
        layout.addView(new MyView(this));
    }
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_second, menu);
        return true;
    }
    class MyView extends View{
   public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

// if required to add this custom view using xml or the graphical layout in eclipse. have to add this constructor
         public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

protected void onDraw(Canvas canvas){
    System.out.println("draw canvas");
    Paint paint = new Paint();
    paint.setColor(0xFFFF0000);
    Rect rect = new Rect();
    rect.set(100, 100, 200, 150);
    canvas.drawRect(rect, paint);
   }
    }
}


C#: Console


To capture key press, print at specific position of console window

class Program
    {
        static void Main(string[] args)
        {
            int i = 0;
            bool running = true;
            int pos = 0;
            int lengthOfLine = 1;
            int diff = 0;
            while (running)
            {
                //Console.Clear();
                if (Console.CursorTop - pos > diff)
                {
                    pos = Console.CursorTop;
                }
                else
                {
                    Console.CursorTop = pos;
                }
                Console.WriteLine("i = " + (i++));
                diff = Console.CursorTop - pos;
             
                if (Console.KeyAvailable)
                {
                    ConsoleKeyInfo key = Console.ReadKey(true);
                    if (key.Key == ConsoleKey.I)
                    {
                        Console.WriteLine("I pressed");
                        //running = false;
                    }
                    else if (key.Key == ConsoleKey.X)
                    {
                        Console.WriteLine("Exit");
                        running = false;
                    }
                }
                Thread.Sleep(40);
            }

        }
    }

Tuesday, August 21, 2012

android: loading and displaying images on canvas


copy and paste image into res\drawable folder in project folder
R.java in "gen" should include this image with an id. Note: filename to be all lower-case

// loading, assuming written in a View class
Bitmap bmp = BitmapFactory.decodeResource(this.getResources(), R.drawable.image_id); 
// displaying
canvas.drawBitmap(bmp, 50, 30, null);

Android: 2d drawing surface

To create a canvas for custom drawing, eg,: for 2d games without using opengl
Create a new class extending SurfaceView, add constructor with 2 arguments (so that it can be used in graphical editor in eclipse too), implement interface SurfaceHolder.Callback

import android.content.Context;
import android.util.AttributeSet;
import android.view.*;

public class MySurface extends SurfaceView implements SurfaceHolder.Callback{
SurfaceHolder holder;

public MySurface(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
holder = this.getHolder();
holder.addCallback(this);

}

public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
System.out.println("surface changed");
}

public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
System.out.println("surface created");
}

public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
System.out.println("surface destroyed");
}

}


This new custom UI will be available for the xml layout file in Eclipse

can create a draw() method to contain all drawing code in there. then call draw() when surfaceCreated(...)

void draw(){
canvas = holder.lockCanvas();
Paint paint = new Paint();
paint.setColor(0xFFFF0000); // ARGB, red
canvas.drawRect(new Rect(10, 20, 100, 50), paint);
holder.unlockCanvasAndPost(canvas);
}


Threading can be used if animation is needed, for example for games.

Sample code snippet:

public class MySurface extends SurfaceView implements SurfaceHolder.Callback, Runnable{
SurfaceHolder holder;
Canvas canvas;
MySprite s = new MySprite();
boolean isRunning = true;
long time = 0;

static final int DELAY = 10;

public MySurface(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
holder = this.getHolder();
holder.addCallback(this);

}

synchronized void draw(){
canvas = holder.lockCanvas();
canvas.drawColor(0xFFDDDDDD); // ARGB , fill whole canvas

// call draw in sprite
s.draw(canvas);

holder.unlockCanvasAndPost(canvas);
}

synchronized void update(){
s.update();
System.out.println((System.currentTimeMillis() - time) + " ms");
time = System.currentTimeMillis();
}

public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
System.out.println("surface changed");
}

public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
System.out.println("surface created");

isRunning = true;
Thread thread = new Thread(this);
thread.start();

time = System.currentTimeMillis();
}

public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
System.out.println("surface destroyed");
isRunning = false;
}

public void run() {
// TODO Auto-generated method stub
try{
while(isRunning){
update();
draw();
Thread.sleep(DELAY);
}
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}

MySprite is a custom class which contains x, y, width, height, its own draw(), update(), init(), cleanup() methods.


Monday, August 20, 2012

wxpython with new WebView

using version 2.9.4

import wx
import wx.html2

app = wx.App(False)
frame = wx.Frame(None, -1, 'A Simple Frame')
browser = wx.html2.WebView.New(frame)
browser.LoadURL("http://www.google.com")
frame.Show()
app.MainLoop()




tried loading local html file with some javascript.
worked so far. tested with jquery. ok too.

import os
browser.LoadURL(os.path.realpath("test.html"))


Tuesday, July 24, 2012

Panda3D & maya


Maya (+x, +y, +z) <=> Panda3D (+x, +z, -y)
Panda3D (+x, +y, +z) <=> Maya (+x, -z, +y)

Panda3D: camera face +Y by default; Maya: Model face +Z as Front

Sample code to add keyboard input:
        self.accept('arrow_up-up', self.moveForward ) # up cursor key released
def moveForward(self):
        self.pos = self.camera.getPos()
        self.pos.y = self.pos.y + 1
        self.camera.setPos(self.pos)
        print self.pos

Sample for mouse input:
self.accept('mouse1-up', self.click)
    
    def click(self):
        if self.mouseWatcherNode.hasMouse():
             print str(self.mouseWatcherNode.getMouseX()) + ", " + str(self.mouseWatcherNode.getMouseY()) # x and y = [-1,1], top left (-1,1), bottom right (1, -1)

Tuesday, May 22, 2012

Panda3D: Maya exporter

used maya2egg****.exe 
kept having error about "procedure entry point not located in some libmmd.dll", etc.

realised that have to copy the exe from panda/bin folder to maya/bin folder

maya2egg -a model -o "output.egg" "input.mb"


m = loader.loadModel("cube.egg")
m.reparentTo(base.render)
m.setPos(0,20,0)

EGG model loaded with texture.

couldn't get the COLLADA model to display textures.


Supported in Panda3d
Currently known scene file types are:
  Bam                             .bam
  Egg                             .egg
  MultiGen                        .flt
  Lightwave                       .lwo
  DXF                             .dxf
  VRML                            .wrl
  DirectX                         .x
  COLLADA                         .dae
  Also available: .ma .mb



Tuesday, May 15, 2012

Python & XML

how to parse XML file
using built-in xml.parsers.expat
steps:
  1. create handlers. eg.: def start_element(name, attrs):
  2. create parser. eg.: p = ParserCreate('utf-8')
  3. link handlers. eg.: p.StartElementHandler = start_element
  4. open file eg.: f = open(filename)
  5. ParseFile(file)
Python IDE summary: Netbeans 6.x looks like better choice than Eclipse in terms of code completion. however, netbeans 7 does not support python plugin. currently using netbeans 6.9.1
no problem in using Netbeans with Panda3D
discover a bug. cannot debug properly in Netbeans 6.9.1. cannot step into a method for multiple PY files. breakpoints do not work in multiple files. can be quite troublesome for debugging.
No issue with Eclipse.

converting from String to int or float using int() or float()
attributes in StartElementHandler is stored in Dictionary. eg.: to access an attribute called x , use attrs['x']

thing to note when using classes and methods, have to keep using 'self' keyword in methods when accessing object properties or methods. same as "this" in java but if you omit it in python, it will default to global variable. 

interesting note: cannot use ( ) parenthesis in "for" statement. eg.: for (x in a): 
instead use "for x in a:"

another interesting note: cannot use the same instance to re-parse another file or string. has to create a new instance of parser to do so. ie. Step 2

Sunday, May 13, 2012

Saturday, April 21, 2012

javascript: String to XML

a quick utility function to convert from string to xml object.
Reference:
http://www.w3schools.com/xml/xml_dom.asp

function stringToXML(text)
{
var xmldoc;
if (window.DOMParser)
{
 var parser=new DOMParser();
 xmldoc=parser.parseFromString(text,"text/xml");
}
else // Internet Explorer
{
 xmldoc=new ActiveXObject("Microsoft.XMLDOM");
 xmldoc.async=false;
 xmldoc.loadXML(text);
}
return xmldoc;
}

Useful properties/methods for XML Object:

  • getElementsByTagName(tagName)
  • childNodes[index]
  • nodeValue
  • getAttribute(atttributeName)
  • setAttribute(name, value)
  • createElement(name)
  • createTextNode(text)
  • appendChild(element)
  • removeChild(element)

Friday, April 13, 2012

WPF Controls in XNA

http://www.c-sharpcorner.com/uploadfile/iersoy/windows-controls-and-wpf-usercontrols-inside-an-xna-game-project/
http://stackoverflow.com/questions/835878/wpf-textbox-not-accepting-input-when-in-elementhost-in-window-forms

But the textbox is still not receiving input.

Alternative is to render a separate window
Window window = new Window();
window.Content = control;
WindowInteropHelper helper = new WindowInteropHelper(window);
 helper.Owner = Window.Handle;
ElementHost.EnableModelessKeyboardInterop(window);
window.Show();


Have to Add Reference:
System.Xaml
WindowsFormsIntegration
System.Windows.Forms
PresentationCore
PresentationFramework

import

using System.Windows;
using System.Windows.Interop;
using System.Windows.Forms.Integration;


Run the program and you will get an error about STAThread
so add "[STAThread]" in eg.: 
Program.cs
just before "static void Main(String[] args)" 

Sunday, April 01, 2012

HTML5 WebSocket server using c#

Use Socket.Listen(10) as per normal.
on Socket.Accept(): the HTML5 client from the browser will initiate a handshake.
grab the request using Socket.Receive(byte[])
C#:

bytes = new byte[1024];
 int bytesRec = client.Receive(bytes);
data += Encoding.ASCII.GetString(bytes, 0, bytesRec);

Example:

"--- Request ---
GET /echo HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:9998
Origin: null
Sec-WebSocket-Key: NBX4xUnlu1QWVPtGE2RFyw==
Sec-WebSocket-Version: 13"

To generate a response back, need a few steps.
Reference: http://en.wikipedia.org/wiki/WebSocket#WebSocket_protocol_handshake

Get the key, eg.: "NBX4xUnlu1QWVPtGE2RFyw=="
append the magic string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" to the key.
Use SHA1 to hash the combined string.
Convert this string to base64

Reference: http://www.gamedev.net/topic/611744-websocket-c-handshake-client-does-not-response-on-handshake/
C#:

string combined = key + magicString;
 SHA1 sha = new SHA1CryptoServiceProvider();
byte[] hash = sha.ComputeHash(Encoding.ASCII.GetBytes(combined));
string acceptKey = Convert.ToBase64String(hash);

so in this case, accept key is "YOBURURfF9giWA8womjw1NpT9fk="

Then form the response.
Example:

"--- Response ---
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: YOBURURfF9giWA8womjw1NpT9fk="

use "\r\n" to end each line. and add an additional "\r\n" to the last line, ie., two "\r\n"

send this thru the socket.
example:

byte[] outputBytes = Encoding.ASCII.GetBytes(output);
 int result = client.Send(outputBytes);

To decode any message from client. using the WebSocket.send(message) method
Reference: http://stackoverflow.com/questions/8125507/how-can-i-send-and-receive-websocket-messages-on-the-server-side

sequence: "one byte which contains the type of data
one byte which contains the length
either two or eight additional bytes if the length did not fit in the second byte
four bytes which are the masks (= decoding keys)
the actual data"

to decode: "decodedByte = encodedByte XOR masks[encodedByteIndex MOD 4]"
C#:

                    bytes = new byte[1024];
                    int bytesRec = client.Receive(bytes);


                    int second = bytes[1] & 127; // AND 0111 1111
                    int maskIndex = 2;
                    if (second < 126)
                    {
                        // length fit in second byte
                        maskIndex = 2;
                    }
                    else if (second == 126)
                    {
                        // next 2 bytes contain length
                        maskIndex = 4;
                    }
                    else if (second == 127)
                    {
                        // next 8 bytes contain length
                        maskIndex = 10;
                    }
                    // get mask
                    byte[] mask = { bytes[maskIndex], 
                                  bytes[maskIndex+1], 
                                  bytes[maskIndex+2], 
                                  bytes[maskIndex+3]};
                    int contentIndex = maskIndex + 4;


                    // decode
                    byte[] decoded = new byte[bytesRec - contentIndex];
                    for (int i = contentIndex, k = 0; i < bytesRec; i++, k++ )
                    {
                        // decoded = byte XOR mask
                        decoded[k] = (byte)(bytes[i] ^ mask[k % 4]);
                    }
                    data = Encoding.UTF8.GetString(decoded, 0, decoded.Length);
                    Console.WriteLine(data);

Wednesday, March 28, 2012

WP7: Isolated Storage

To store app data so that it can be restored when app is tombstoned/deactivated and then restored. stored in key/value pairs


IsolatedStorageSettings setting = IsolatedStorageSettings.ApplicationSettings;
 if (!setting.Contains("rounds")) // check if key exists
 {
     setting.Add("rounds", rounds); // if not, create new key
}
 else
{
      setting["rounds"] = rounds; // if exists, just change the value
}

Reference: http://create.msdn.com/en-US/education/quickstarts/Isolated_Storage

Tuesday, March 27, 2012

WP7: Canvas, Random, 2D Array & Timer



// create a rectangle and fill it with color
Rectangle r = new Rectangle();
 r.Width = r.Height = 50;
r.Fill = new SolidColorBrush(Colors.Orange);
 r.Stroke = new SolidColorBrush(Colors.Black);
 r.StrokeThickness = 3;
// add to canvas
canvas1.Children.Add(r);
// set position

Canvas.SetLeft(r, x);
 Canvas.SetTop(r, y);


// random generator
Random rand = new Random();
int n = rand.Next(maxNumber); // integer :0 to less than maxNumber


// 2D Array
int[,] containers = new int[w, h];

for (int i = 0; i < w; i++ )
 {
       for (int k = 0; k < h; k++)
      {
           containers[i, k] = -1;
       }
 }


// Timer
using System.Windows.Threading;
DispatcherTimer timer = new DispatcherTimer();

timer.Interval = TimeSpan.FromSeconds(5); 
timer.Tick += new EventHandler(timer_Tick);


void timer_Tick(object sender, EventArgs e)
{
     // do something 
 }

Monday, March 26, 2012

WP7: Button MouseDown and Rotate

Interesting that the Button control in silverlight does not support mousedown event.
however, to capture touch down event on the button, has to change the ClickMode of the Button control to "Press" instead of "Release"
and then capture the mousedown event using the "Click" event

Reference: http://www.silverlightshow.net/items/Tip-How-to-handle-the-MouseLeftButtonDown-and-MouseLeftButtonUp-events-of-the-Button-control.aspx

Rotation done using the following:
<Button.RenderTransform>
   <RotateTransform Angle="180" CenterX="100" CenterY="25"/>
</Button.RenderTransform>

Friday, March 09, 2012

Create User accounts in Mac OS X

Reference: http://serverfault.com/questions/20702/how-do-i-create-user-accounts-from-the-terminal-in-mac-os-x-10-5


# Find out the next available user ID
MAXID=$(dscl . -list /Users UniqueID | awk '{print $2}' | sort -ug | tail -1)
USERID=$((MAXID+1))

# Create the user account
dscl . -create /Users/$USERNAME
dscl . -create /Users/$USERNAME UserShell /bin/bash
dscl . -create /Users/$USERNAME RealName "$FULLNAME"
dscl . -create /Users/$USERNAME UniqueID "$USERID"
dscl . -create /Users/$USERNAME PrimaryGroupID 20
dscl . -create /Users/$USERNAME NFSHomeDirectory /Users/$USERNAME

dscl . -passwd /Users/$USERNAME $PASSWORD

# Add user to group
dseditgroup -o edit -t user -a $USERNAME $GROUP

# Create the home directory
createhomedir -c -u $USERNAME

Wednesday, March 07, 2012

Phonegap: HTML5 vs DOM/CSS

Tested and compared using HTML5 canvas drawing and DOM elements with CSS
strangely, when tested on an android 4 device, HTML5 canvas drawing cause the app to black out after a while.
using DOM elements and CSS2, seems ok.
performance pretty similar



Saturday, February 18, 2012

android: phone gap screen resolution

hmm... seems like 320x480 is quite safe for canvas size. 


Thursday, February 16, 2012

Android: PhoneGap

Follow instructions to install and set up
http://phonegap.com/start#android

to debug. need to open LogCat.
strange console.log() did not output here.
in the end, have to use Window > Show View > Other... > Android > LogCat (deprecated)

had problem connecting to device on debug mode. happen to find out Easy Tether is messing with USB debugging.

so refer to: http://stackoverflow.com/questions/4680637/mac-os-x-10-6-6-and-adb-devices-fails-to-list-android-devices


sudo kextunload /System/Library/Extensions/EasyTetherUSBEthernet.kext
sudo rm -rf /System/Library/Extensions/EasyTetherUSBEthernet.kext

working now.

using dreamweaver to edit the HTML and JS. test it in chrome before launching in emulator or device.






Wednesday, February 15, 2012

Android: navigation between screens

Each screen called "Activity"

create a new class that extends from "Activity"
create a new Android XML file to set up the layout

make sure that this new Activity is included in the AndroidManifest.xml.
in eclipse, open the AndroidManifest.xml > Application tab > Application nodes > Add... > Create a new element at top level > Activity.
Name: Browse > select new Activity class created

easier way is to edit the xml manually and add
<activity android:name="{name of new Activity subclass}"></activity>
in the <application> tag.

using Singleton design pattern, data can be passed to next screen.

For example:


public class Apple {
public static int number = 1;
double price = 0.5;
int size = 2;
String color = "red";
public static String name = "Apple";
public static Apple instance;
public void grow()
{
size++;
}
public String getColor()
{
return color;
}
}

in main Activity subclass:

Apple a = new Apple();
Apple.instance = a;

Apple.number++;
// et is editable text UI
Apple.name = et.getText().toString();
a.grow();


// go to next screen
Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);

next Activity subclass:


public class NextActivity extends Activity implements View.OnClickListener{
Button b;
TextView tv;
@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.next);
        tv = (TextView)this.findViewById(R.id.textView1);
        b = (Button) this.findViewById(R.id.button1);
        tv.setText("Hello, " + Apple.name + ", size: " + Apple.instance.size+ ". number of apple: " + Apple.number);
        b.setOnClickListener(this);
}


public void onClick(View v) {
// TODO Auto-generated method stub
// end this activity to go back to prev screen
this.finish();
}
}



Tuesday, February 14, 2012

Android: Hello World, XML, Java

Follow instructions to install Android SDK, Eclipse, ADT plugin
Set up AVD
Start new Android project

in res\layout\main.xml
open it to set up layout.
set id. strange why android makes programmer to add "@+id/" before the id. more memory load for the programmers.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello World" android:id="@+id/hello_txt"/>

    <EditText
        android:id="@+id/editText1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="123">

        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/button1"
        android:layout_width="146dp"
        android:layout_height="wrap_content"
        android:text="Press me!" />

</LinearLayout>

HelloActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.widget.*;

public class HelloActivity extends Activity implements View.OnClickListener{
TextView tv;
Button b;
EditText et;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        tv = (TextView)this.findViewById(R.id.hello_txt);
        b = (Button) this.findViewById(R.id.button1);
        et = (EditText) this.findViewById(R.id.editText1);
        b.setOnClickListener(this);
    }
    // implement interface View.OnClickListener method
public void onClick(View v) {
// TODO Auto-generated method stub
tv.setText("Hello, " + et.getText());
}
}



Thursday, February 09, 2012

WP7: XML reading from RSS

WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.OpenReadAsync(new Uri("http://www.todayonline.com/RSS/Todayonline", UriKind.Absolute));

void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
    XmlReader reader = XmlReader.Create(e.Result);
    reader.ReadToFollowing("title");
    // assume there is a textbox named "textBox1"
    textBox1.Text = reader.ReadElementContentAsString() + "\n\n";
}

Windows 7 Mango Training - 8-9 Feb

Silverlight, C# in windows 7 phone
Summary of lessons learnt:
  1. same as WPF technology. XAML for layout of UI with CS controlling interactivity and behaviour of app. similar to Flex with MXML and AS 
  2. no Console.Writeline(), have to use System.Diagnostics.Debug.WriteLine()
  3. Loading and Activating events has 10 sec limit. if exceeded OS will terminate app
  4. Loading and Activating event is mutually exclusive
  5. NavigationService.Navigate(Uri) to move from one XAML page to another. eg.: NavigationService.Navigate(new Uri("/IntroPage.xaml", UriKind.RelativeOrAbsolute));
  6. Dormant and Tombstone states
  7. recall x:Name attribute for XAML elements for C# code integration and reference
  8. use Blend to create animation (new StoryBoard, record mode. use timeline) and use Visual Studio to call the animation for interactivity. make sure that XAML file is saved before switching to and fro the 2 tools. file can be overwritten if not careful. 
  9. Easing in blend for a animation segment is set at the end keyframe. eg.: if bounce easing is to be applied between frame 1 and 2, then easing is to be set in frame 2, instead of 1. unlike Flash.
  10. PNG image for App Icon
  11. use System.Windows.Threading.DisptacherTimer to perform timer functions instead of Timer due to access restriction of UI across threads
  12. To change default XAML for a app, change the WMAppManifest.xml in the project to reflect the xaml page in the DefaultTask element.
  13. Touch.FrameReported event (eg.: Touch.FrameReported += new TouchFrameEventHandler(Touch_FrameReported); ) to capture multitouch events on screen. but be careful of the reference point when getting the TouchPoint. Example: TouchPoint pt = e.GetTouchPoints(ContentPanel)[0]; // gets 1st touch with respect to UI Element named "ContentPanel"
  14. for network security access issues when debugging app, may have to run Visual Studio as administrator. right click on "Visual Studio ..." > "Run as administrator"
  15. personal preference: show line numbers. Tool > Options > check "Show all options" > Text Editor > All languages > Display > check "Line numbers"
  16. use WebClient for network HTTP communication
  17. System.Net.Socket supported