# HG changeset patch # User John Tsiombikas # Date 1452523876 -7200 # Node ID ef0c22554406d8b8fadd1ba5305aaf782cdf2486 cloth sim test, initial commit diff -r 000000000000 -r ef0c22554406 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Mon Jan 11 16:51:16 2016 +0200 @@ -0,0 +1,4 @@ +\.swp$ +\.o$ +\.d$ +^cloth$ diff -r 000000000000 -r ef0c22554406 Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Mon Jan 11 16:51:16 2016 +0200 @@ -0,0 +1,19 @@ +src = $(wildcard src/*.cc) +obj = $(src:.cc=.o) +bin = cloth + +sys := $(shell uname -s | tr '[:upper:]' '[:lower:]' | sed 's/mingw.*/mingw/') + +CXXFLAGS = -pedantic -Wall -g +LDFLAGS = $(libgl_$(sys)) -lgmath + +libgl_linux = -lGL -lGLU -lglut -lGLEW +libgl_darwin = -framework OpenGL -framework GLUT -lGLEW +libgl_mingw = -lopengl32 -lglu32 -lglut32 -lglew32 + +$(bin): $(obj) + $(CXX) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 000000000000 -r ef0c22554406 src/cloth.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cloth.cc Mon Jan 11 16:51:16 2016 +0200 @@ -0,0 +1,173 @@ +#include +#include +#include "cloth.h" +#include "object.h" +#include "opengl.h" + +Cloth::Cloth() +{ + mass = 1.0; + elast = 0.8; + spring_k = 1.0; + grav = Vector3(0, -9, 0); +} + +void Cloth::create_rect(int x, int y, float width, float height) +{ + int num = x * y; + float dx = width / (float)x; + float dy = height / (float)y; + + masses.resize(num); + conn.resize(num); + for(int i=0; i= x || ny < 0 || ny >= y) continue; + + int nidx = ny * x + nx; + float dist = length(masses[idx].pos - masses[nidx].pos); + + conn[idx][nidx] = conn[nidx][idx] = dist; + } + } + + ++idx; + } + } +} + +void Cloth::transform(const Matrix4x4 &xform) +{ + for(size_t i=0; iintersect(ray, hit) && hit->t < nearest.t) { + nearest = *hit; + } + } + + if(nearest.obj) { + *hit = nearest; + return true; + } + return false; +} + +void Cloth::draw() const +{ + glPushAttrib(GL_ENABLE_BIT); + + glPointSize(7.0); + glEnable(GL_POINT_SMOOTH); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // draw masses + glBegin(GL_POINTS); + for(size_t i=0; i +#include +#include "object.h" + +using namespace gph; + +struct ClothMass { + Vector3 pos, vel; + bool fixed; +}; + +class Cloth { +private: + float mass, elast; // global mass attributes + float spring_k; // spring constant for all springs + Vector3 grav, forces; + + std::vector masses; + std::vector > conn; // spring lengths, <0 means not connected + + std::vector colliders; + + bool find_collision(const Ray &ray, HitPoint *hit) const; + +public: + Cloth(); + + void create_rect(int x, int y, float width, float height); + + void transform(const Matrix4x4 &xform); + + void add_collider(Object *o); + + void step(float dt); + + void draw() const; +}; + +#endif // CLOTH_H_ diff -r 000000000000 -r ef0c22554406 src/main.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main.cc Mon Jan 11 16:51:16 2016 +0200 @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#ifdef __APPLE__ +#include +#else +#include +#endif +#include "object.h" +#include "cloth.h" + +bool init(); +void cleanup(); +void display(); +void idle(); +void reshape(int x, int y); +void keyboard(unsigned char key, int x, int y); +void mouse(int bn, int st, int x, int y); +void motion(int x, int y); + +float cam_theta, cam_phi, cam_dist = 8; + +Cloth cloth; + +int main(int argc, char **argv) +{ + glutInit(&argc, argv); + glutInitWindowSize(800, 600); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow("foo"); + + glutDisplayFunc(display); + glutIdleFunc(idle); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutMouseFunc(mouse); + glutMotionFunc(motion); + + if(!init()) { + return 1; + } + atexit(cleanup); + + glutMainLoop(); +} + + +bool init() +{ + glewInit(); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + //glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + + cloth.create_rect(32, 32, 10, 10); + + Matrix4x4 xform = Matrix4x4(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 1, 0, 1); + cloth.transform(xform); + + + return true; +} + +void cleanup() +{ +} + +void display() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -cam_dist); + glRotatef(cam_phi, 1, 0, 0); + glRotatef(cam_theta, 0, 1, 0); + + cloth.draw(); + + glutSwapBuffers(); + assert(glGetError() == GL_NO_ERROR); +} + +void idle() +{ + glutPostRedisplay(); +} + +void reshape(int x, int y) +{ + glViewport(0, 0, x, y); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(50.0, (float)x / (float)y, 0.5, 500.0); +} + +void keyboard(unsigned char key, int x, int y) +{ + switch(key) { + case 27: + exit(0); + } +} + +static bool bnstate[16]; +static int prev_x, prev_y; + +void mouse(int bn, int st, int x, int y) +{ + prev_x = x; + prev_y = y; + bnstate[bn - GLUT_LEFT_BUTTON] = st == GLUT_DOWN; +} + +void motion(int x, int y) +{ + int dx = x - prev_x; + int dy = y - prev_y; + prev_x = x; + prev_y = y; + + if(!dx && !dy) return; + + if(bnstate[0]) { + cam_theta += dx * 0.5; + cam_phi += dy * 0.5; + + if(cam_phi < -90) cam_phi = -90; + if(cam_phi > 90) cam_phi = 90; + } + if(bnstate[2]) { + cam_dist += dy * 0.1; + if(cam_dist < 0.0) cam_dist = 0.0; + } +} diff -r 000000000000 -r ef0c22554406 src/object.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/object.cc Mon Jan 11 16:51:16 2016 +0200 @@ -0,0 +1,27 @@ +#include "object.h" +#include "opengl.h" + +Object::~Object() +{ +} + +Triangle::Triangle() +{ +} + +Triangle::Triangle(const Vector3 &a, const Vector3 &b, const Vector3 &c) +{ + v[0] = a; + v[1] = b; + v[2] = c; + normal = normalize(cross(b - a, c - a)); +} + +bool Triangle::intersect(const Ray &ray, HitPoint *pt) const +{ + return false; +} + +void Triangle::draw() const +{ +} diff -r 000000000000 -r ef0c22554406 src/object.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/object.h Mon Jan 11 16:51:16 2016 +0200 @@ -0,0 +1,37 @@ +#ifndef OBJECT_H_ +#define OBJECT_H_ + +#include + +using namespace gph; + +class Object; + +struct HitPoint { + float t; + Vector3 pos, normal; + Ray ray; + Object *obj; +}; + +class Object { +public: + virtual ~Object(); + + virtual bool intersect(const Ray &ray, HitPoint *pt) const = 0; + virtual void draw() const = 0; +}; + +class Triangle : public Object { +public: + Vector3 v[3]; + Vector3 normal; + + Triangle(); + Triangle(const Vector3 &a, const Vector3 &b, const Vector3 &c); + + virtual bool intersect(const Ray &ray, HitPoint *pt) const; + virtual void draw() const; +}; + +#endif diff -r 000000000000 -r ef0c22554406 src/opengl.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/opengl.h Mon Jan 11 16:51:16 2016 +0200 @@ -0,0 +1,52 @@ +/* +Stereoscopic tunnel for iOS. +Copyright (C) 2011-2015 John Tsiombikas + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + + +#ifndef OPENGL_H_ +#define OPENGL_H_ + +#ifdef HAVE_CONFIG_H_ +#include "config.h" +#endif + +#if defined(IPHONE) || defined(__IPHONE__) +#include + +#define glClearDepth glClearDepthf +#define GLDEF +#include "sanegl.h" + +#elif defined(ANDROID) +#include +#include +#define GLDEF +#include "sanegl.h" + +#else + +#include + +#ifdef __APPLE__ +#include +#else +#include +#endif /* __APPLE__ */ + +#endif /* IPHONE */ + +#endif /* OPENGL_H_ */