Created
May 26, 2012 21:17
-
-
Save SecondReality/2795343 to your computer and use it in GitHub Desktop.
Flexer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Flexer.h | |
// OpenGLESTest | |
// | |
// Created by Steven Mark Rose on 26/09/2010. | |
// Copyright 2010 Second Reality. All rights reserved. | |
// | |
// The Flexer class is used to modify a vertex buffer so it can bend and trail and follow a moving point. | |
// Example uses are: Mouse Tails and Fish Bodies. | |
// After it has been initialised its length cannot be changed. | |
#import <Foundation/Foundation.h> | |
#import <OpenGLES/ES1/gl.h> | |
#import <OpenGLES/ES1/glext.h> | |
#import "Vector2D.h" | |
@interface Flexer : NSObject | |
{ | |
@private | |
int controlPointCount; | |
NSMutableArray* controlPoints; | |
GLfloat* vertexBuffer; | |
GLfloat* textureBuffer; | |
int vertexCount; | |
float controlPointDistance; | |
} | |
-(id)initWithLength:(int)length pointDistance:(float)pointDistance; | |
-(void)updateHeadPosition:(Vector2D)newHeadPosition direction:(Vector2D)direction width:(float)width; | |
@property GLfloat* vertexBuffer; | |
@property GLfloat* textureBuffer; | |
@property (readonly)int vertexCount; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// Flexer.m | |
// OpenGLESTest | |
// | |
// Created by Steven Mark Rose on 26/09/2010. | |
// Copyright 2010 Second Reality. All rights reserved. | |
// | |
#import "Flexer.h" | |
#import "Vector2D.h" | |
@implementation Flexer | |
@synthesize vertexBuffer; | |
@synthesize textureBuffer; | |
@synthesize vertexCount; | |
-(id)initWithLength:(int)length pointDistance:(float)pointDistance | |
{ | |
if(self=[super init]) | |
{ | |
controlPointCount=length; | |
controlPointDistance = pointDistance; | |
controlPoints=[[NSMutableArray alloc] init]; | |
for(int i=0; i<controlPointCount; i++) | |
{ | |
Vector2DWrapper * vectorWrapper = [[Vector2DWrapper alloc] init]; | |
[controlPoints addObject:vectorWrapper]; | |
[vectorWrapper release]; | |
} | |
vertexCount=controlPointCount*2; | |
vertexBuffer = malloc(vertexCount*3*sizeof(float)); | |
textureBuffer = malloc(vertexCount*2*sizeof(float)); | |
// Initialise texture buffer: | |
float increase = 1.0f/(controlPointCount-1); | |
float textureOffset=0.0f; | |
for(int i=0; i<vertexCount*2; i+=4) | |
{ | |
textureBuffer[i]=textureOffset; | |
textureBuffer[i+1]=1.0f; | |
textureBuffer[i+2]=textureOffset; | |
textureBuffer[i+3]=0.0f; | |
textureOffset+=increase; | |
} | |
} | |
return self; | |
} | |
-(void)dealloc | |
{ | |
free(vertexBuffer); | |
vertexBuffer=NULL; | |
free(textureBuffer); | |
textureBuffer=NULL; | |
[controlPoints release]; | |
[super dealloc]; | |
} | |
-(void)updateHeadPosition:(Vector2D)newHeadPosition direction:(Vector2D)directionIn width:(float)width | |
{ | |
Vector2DWrapper * headControlPointWrapper=[controlPoints objectAtIndex: 0]; | |
headControlPointWrapper->v=newHeadPosition; | |
// Calculate the position of the first two vertices: | |
{ | |
Vector2D perp = multiply(rotateBy90DegreesClockwise(directionIn), 0.10f); | |
Vector2D point1 = add(newHeadPosition, perp); | |
Vector2D point2 = subtract(newHeadPosition, perp); | |
vertexBuffer[0]=point1.x; | |
vertexBuffer[1]=point1.y; | |
vertexBuffer[2]=-1.8f; | |
vertexBuffer[3]=point2.x; | |
vertexBuffer[4]=point2.y; | |
vertexBuffer[5]=-1.8f; | |
} | |
// Update the remaining control points: | |
for(int i=1; i<controlPointCount; i++) | |
{ | |
Vector2DWrapper* controlPointWrapper = [controlPoints objectAtIndex: i]; | |
Vector2DWrapper* previousControlPointWrapper = [controlPoints objectAtIndex: i-1]; | |
// Calculate the directional vector from the previous control point to this control point: | |
Vector2D direction = normalize(subtract(controlPointWrapper->v, previousControlPointWrapper->v)); | |
controlPointWrapper->v=add(previousControlPointWrapper->v, multiply(direction, controlPointDistance)); | |
} | |
// Update the vertices: | |
// Update the remaining control points: | |
for(int i=1; i<controlPointCount; i++) | |
{ | |
Vector2DWrapper* previousControlPointWrapper = [controlPoints objectAtIndex: i-1]; | |
Vector2DWrapper* controlPointWrapper = [controlPoints objectAtIndex: i]; | |
Vector2D previousControlPoint = previousControlPointWrapper->v; | |
Vector2D controlPoint = controlPointWrapper->v; | |
// Calculate the directional vector from the previous control point to this control point: | |
Vector2D direction = normalize(subtract(controlPoint, previousControlPoint)); | |
Vector2D perp; | |
if(i<controlPointCount-1) | |
{ | |
Vector2DWrapper * nextControlPointWrapper = [controlPoints objectAtIndex: i+1]; | |
Vector2D directionToNextControlPoint = normalize( subtract(nextControlPointWrapper->v, controlPoint)); | |
// Adding two normalised vectors together like this is dangerous because they could point | |
// in opposite directions and nullify to give (0,0) | |
perp = normalize(rotateBy90DegreesClockwise(add(direction, directionToNextControlPoint))); | |
// Test if perp is NAN: | |
if(perp.x!=perp.x) | |
{ | |
perp = rotateBy90DegreesClockwise(direction); | |
} | |
} | |
else | |
{ | |
perp = rotateBy90DegreesClockwise(direction); | |
} | |
perp=multiply(perp, width); | |
Vector2D point2 = add(controlPoint, perp); | |
Vector2D point1 = subtract(controlPoint, perp); | |
int n=i; | |
vertexBuffer[n*2*3]=point1.x; | |
vertexBuffer[n*2*3+1]=point1.y; | |
vertexBuffer[n*2*3+2]=-1.8f; | |
vertexBuffer[n*2*3+3]=point2.x; | |
vertexBuffer[n*2*3+4]=point2.y; | |
vertexBuffer[n*2*3+5]=-1.8f; | |
} | |
/* | |
for(int i=0; i<controlPointCount*2; i++) | |
{ | |
NSLog(@"Vertex %d: %f,%f,%f", i, vertexBuffer[i*3+0], vertexBuffer[i*3+1], vertexBuffer[i*3+2]); | |
} | |
*/ | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment