Boris Mezhibovskiy - programmer |
mez13526@gmail.com |
In Tumble, my senior game project, players can select objects with the mouse and place it in the world. The object needs to snap to whatever is underneath it. This function computes the position of that object: |
Click to hide code
/* Boris Mezhibovskiy */ //Calculates the position of the mouseObject so that it rests on the target object. Vec3 Editor::objectPosition(ObjectInstance* mouseObject, //the object being held by the mouse ObjectInstance* targetObject, //the mouse object needs to rest on this //the intersection point between the mouse ray and the target object Vec3 intersectionPoint, //the normal of the target object at the intersection point. (might be inward) Vec3 intersectionNormal) { //compensating for random inward-facing normals. PhysicsObject* physObjC = static_cast<PhysicsObject*>(targetObject->objectTypes[PHYSICS_COMPONENT]); GraphicObject* graphObjC = static_cast<GraphicObject*>(targetObject->objectTypes[GRAPHIC_COMPONENT]); Vec3 objPos = physObjC->GetPos(); Vec3 dim = graphObjC->getDimensions(); float epsilon = min(min(dim.x,dim.y),dim.z)/4.0f; //if the point at the end of the normal is closer to the center than the surface, the normal is inward. float l1=abs(D3DXVec3LengthSq(&((intersectionPoint+intersectionNormal*epsilon)-objPos))); float l2=abs(D3DXVec3LengthSq(&(intersectionPoint-objPos))); if(l1<l2) { intersectionNormal = -intersectionNormal; } //finding the minimum and maximum values of each point for each axis in the mouse-object's collision poly CollisionObject* collideObjC = static_cast<CollisionObject*>(mouseObject->objectTypes[COLLISION_COMPONENT]); float maxX,maxY,maxZ,minX,minY,minZ; maxX=maxY=maxZ=-FLT_MAX; minX=minY=minZ= FLT_MAX; int numPoints = collideObjC->object->GetPointCount(); for(int i=0;i<numPoints;++i) { Vec3 currentPoint = collideObjC->object->GetPoint(i); if(currentPoint.x<minX) minX = currentPoint.x; if(currentPoint.y<minY) minY = currentPoint.y; if(currentPoint.z<minZ) minZ = currentPoint.z; if(currentPoint.x>maxX) maxX = currentPoint.x; if(currentPoint.y>maxY) maxY = currentPoint.y; if(currentPoint.z>maxZ) maxZ = currentPoint.z; } //calculating the offset vector from the intersection point that the mouse object's position should be. Vec3 radius(((maxX - minX)/2.0f) * intersectionNormal.x, ((maxY - minY)/2.0f) * intersectionNormal.y, ((maxZ - minZ)/2.0f) * intersectionNormal.z); return intersectionPoint+radius; } |
In the HLSL pixel shader of Tumble (my senior game project), phong lighting normals are affected by a height map without passing tangents and bitangents through the vertices: |
Click to hide code
/* Boris Mezhibovskiy */ //sampling the current pixel and 4 pixels surrounding it. //the x coordinate is inverted because the height map x is inverted. float me = tex2D(heightMapSampler,float2(1.0-(IN.tex.x),IN.tex.y)).x; float n = tex2D(heightMapSampler,float2(1.0-(IN.tex.x),IN.tex.y+1.0/heightMapSizeY)).x; float s = tex2D(heightMapSampler,float2(1.0-(IN.tex.x),IN.tex.y-1.0/heightMapSizeY)).x; float e = tex2D(heightMapSampler,float2(1.0-(IN.tex.x+1.0/heightMapSizeX),IN.tex.y)).x; float w = tex2D(heightMapSampler,float2(1.0-(IN.tex.x-1.0/heightMapSizeX),IN.tex.y)).x; //find perpendicular vector to norm: float3 temp = norm; //a temporary vector that is not parallel to norm if(norm.x==1) temp.y+=0.5; else temp.x+=0.5; //form a basis with norm being one of the axes: float3 perp1 = normalize(cross(norm,temp)); float3 perp2 = normalize(cross(norm,perp1)); //use the basis to move the normal in its own space by the offset float3 normalOffset = -bumpHeightScale*(((n-me)-(s-me))*perp1 + ((e-me)-(w-me))*perp2); norm += normalOffset; norm = normalize(norm); |
I use a custom memory manager to detect many memory bugs. This function gets called whenever memory is freed, and checks for anomalies: |
Click to hide code
/* Boris Mezhibovskiy */ MemoryDebugger::Allocation* MemoryDebugger::removeAllocation(void* pMem, ALLOCATION_TYPE type) throw(MEMORY_EXCEPTION) { if(alreadyDeleted(pMem)) { throw DOUBLE_DELETE; } if(!allocations) { throw INVALID_DELETE; } else { Allocation* currentAlloc = allocations; Allocation* prevAlloc = NULL; while(currentAlloc) { if(currentAlloc->pMem == pMem) { if(currentAlloc->type != type) { //new/delete mismatch throw NEW_DELETE_MISMATCH; } //remove it from the list if(!prevAlloc) { allocations = allocations->next; } else { prevAlloc->next = currentAlloc->next; } //add it to deleted list instead of freeing it currentAlloc->next = NULL; Allocation* currentDeletedAllocation = deletedAllocations; if(!currentDeletedAllocation) deletedAllocations = currentAlloc; else { while(currentDeletedAllocation->next) { currentDeletedAllocation = currentDeletedAllocation->next; } currentDeletedAllocation->next = currentAlloc; } return currentAlloc; } prevAlloc = currentAlloc; currentAlloc = currentAlloc->next; } //random delete throw INVALID_DELETE; } return 0; } |