eqemu

diff src/mesh.cc @ 4:3d3656360a82

rendering properly, added picking, almost done...
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 17 Jul 2014 08:51:17 +0300
parents f9274bebe55e
children 2656099aff12
line diff
     1.1 --- a/src/mesh.cc	Thu Jul 17 02:35:19 2014 +0300
     1.2 +++ b/src/mesh.cc	Thu Jul 17 08:51:17 2014 +0300
     1.3 @@ -1,5 +1,6 @@
     1.4  #include <stdio.h>
     1.5  #include <string.h>
     1.6 +#include <math.h>
     1.7  #include <GL/glew.h>
     1.8  #include "mesh.h"
     1.9  
    1.10 @@ -8,8 +9,9 @@
    1.11  Mesh::Mesh()
    1.12  {
    1.13  	buf_valid = ALL_VALID;
    1.14 +	bsph_valid = false;
    1.15  
    1.16 -	for(int i=0; i<vcount; i++) {
    1.17 +	for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
    1.18  		attr[i] = 0;
    1.19  		attr_size[i] = 0;
    1.20  		buf_valid &= ~(1 << i);
    1.21 @@ -20,7 +22,7 @@
    1.22  
    1.23  Mesh::~Mesh()
    1.24  {
    1.25 -	for(int i=0; i<vcount; i++) {
    1.26 +	for(int i=0; i<NUM_MESH_ATTRIBS; i++) {
    1.27  		delete [] attr[i];
    1.28  	}
    1.29  	glDeleteBuffers(NUM_MESH_ATTRIBS, vbo);
    1.30 @@ -28,18 +30,26 @@
    1.31  
    1.32  float *Mesh::set_attrib(int aidx, int count, int elemsz, float *data)
    1.33  {
    1.34 -	if(attr[aidx]) {
    1.35 -		delete [] attr[aidx];
    1.36 -	}
    1.37 +	delete [] attr[aidx];
    1.38  	attr[aidx] = new float[count * elemsz];
    1.39 +	memcpy(attr[aidx], data, count * elemsz * sizeof *data);
    1.40 +	vcount = count;
    1.41  	attr_size[aidx] = elemsz;
    1.42  	buf_valid &= ~(1 << aidx);
    1.43 +
    1.44 +	if(aidx == MESH_ATTR_VERTEX) {
    1.45 +		bsph_valid = false;
    1.46 +	}
    1.47 +
    1.48  	return attr[aidx];
    1.49  }
    1.50  
    1.51  float *Mesh::get_attrib(int aidx)
    1.52  {
    1.53  	buf_valid &= ~(1 << aidx);
    1.54 +	if(aidx == MESH_ATTR_VERTEX) {
    1.55 +		bsph_valid = false;
    1.56 +	}
    1.57  	return attr[aidx];
    1.58  }
    1.59  
    1.60 @@ -50,6 +60,8 @@
    1.61  
    1.62  void Mesh::draw() const
    1.63  {
    1.64 +	if(!vcount) return;
    1.65 +
    1.66  	update_buffers();
    1.67  
    1.68  	if(!vbo[MESH_ATTR_VERTEX]) {
    1.69 @@ -84,6 +96,18 @@
    1.70  	}
    1.71  }
    1.72  
    1.73 +BSphere &Mesh::get_bounds()
    1.74 +{
    1.75 +	calc_bsph();
    1.76 +	return bsph;
    1.77 +}
    1.78 +
    1.79 +const BSphere &Mesh::get_bounds() const
    1.80 +{
    1.81 +	calc_bsph();
    1.82 +	return bsph;
    1.83 +}
    1.84 +
    1.85  void Mesh::update_buffers() const
    1.86  {
    1.87  	if(buf_valid == ALL_VALID) {
    1.88 @@ -99,3 +123,34 @@
    1.89  		}
    1.90  	}
    1.91  }
    1.92 +
    1.93 +void Mesh::calc_bsph() const
    1.94 +{
    1.95 +	if(bsph_valid || !vcount) {
    1.96 +		return;
    1.97 +	}
    1.98 +
    1.99 +	Vector3 center;
   1.100 +
   1.101 +	float *vptr = attr[MESH_ATTR_VERTEX];
   1.102 +	for(int i=0; i<vcount; i++) {
   1.103 +		center = center + Vector3(vptr[0], vptr[1], vptr[2]);
   1.104 +		vptr += 3;
   1.105 +	}
   1.106 +	center = center * (1.0f / (float)vcount);
   1.107 +
   1.108 +	float max_lensq = 0.0f;
   1.109 +	vptr = attr[MESH_ATTR_VERTEX];
   1.110 +	for(int i=0; i<vcount; i++) {
   1.111 +		Vector3 v = Vector3(vptr[0], vptr[1], vptr[2]) - center;
   1.112 +		float lensq = dot(v, v);
   1.113 +		if(lensq > max_lensq) {
   1.114 +			max_lensq = lensq;
   1.115 +		}
   1.116 +	}
   1.117 +
   1.118 +	bsph.set_center(center);
   1.119 +	bsph.set_radius(sqrt(max_lensq));
   1.120 +
   1.121 +	bsph_valid = true;
   1.122 +}