// // Viewport.m // XNI // // Created by Matej Jan on 23.9.10. // Copyright 2010 Retronator. All rights reserved. // #import "Viewport.h" #import "Retronator.Xni.Framework.h" @implementation Viewport - (id) init { self = [super init]; if (self != nil) { minDepth = 0; maxDepth = 1; } return self; } - (float) aspectRatio { return (float)width/(float)height; } @synthesize height; @synthesize maxDepth; @synthesize minDepth; - (Rectangle *) titleSafeArea { int border = height * 0.05; return [Rectangle rectangleWithX:x + border y:y + border width:width - 2 * border height:height - 2* border]; } @synthesize width; @synthesize x; @synthesize y; - (Vector3 *) project:(Vector3 *)source projection:(Matrix *)projection view:(Matrix *)view world:(Matrix *)world { Vector4 *projectionSpace = [Vector4 vectorWithX:source.x y:source.y z:source.z w:1]; [[[projectionSpace transformWith:world] transformWith:view] transformWith:projection]; projectionSpace.z *= (maxDepth - minDepth); [projectionSpace multiplyBy:1/projectionSpace.w]; float resultX = x + (projectionSpace.x + 1) / 2 * width; float resultY = y - (projectionSpace.y - 1) / 2 * height; float resultZ = minDepth + projectionSpace.z; return [Vector3 vectorWithX:resultX y:resultY z:resultZ]; } - (Vector3 *) unproject:(Vector3 *)source projection:(Matrix *)projection view:(Matrix *)view world:(Matrix *)world { float projectionX = (source.x - x) * 2 / width - 1; float projectionY = -((source.y - y) * 2 / height) + 1; float projectionZ = (source.z - minDepth) / (maxDepth - minDepth); Vector4Struct objectSpace = Vector4Make(projectionX,projectionY,projectionZ,1); MatrixStruct m = *projection.data; MatrixInvert(&m); Vector4Transform(&objectSpace, &m, &objectSpace); m = *view.data; MatrixInvert(&m); Vector4Transform(&objectSpace, &m, &objectSpace); m = *world.data; MatrixInvert(&m); Vector4Transform(&objectSpace, &m, &objectSpace); Vector4Multiply(&objectSpace, 1/objectSpace.w, &objectSpace); return [Vector3 vectorWithX:objectSpace.x y:objectSpace.y z:objectSpace.z]; } @end