mirror of
https://github.com/devZoGok/vb01.git
synced 2026-08-26 19:43:30 +00:00
raycasting 1st attempt
This commit is contained in:
+1
-1
@@ -12,7 +12,7 @@ link_directories(/usr/lib/)
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
set(gui text.cpp rectangle.cpp)
|
||||
set(utils util.cpp)
|
||||
set(math quaternion.cpp vector.cpp)
|
||||
set(math quaternion.cpp vector.cpp ray.cpp)
|
||||
set(render waterPlane.cpp particleEmitter.cpp camera.cpp light.cpp material.cpp mesh.cpp model.cpp node.cpp quad.cpp box.cpp root.cpp shader.cpp texture.cpp)
|
||||
|
||||
add_library(vb01 SHARED main.cpp ${render} ${math} ${utils} ${gui})
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace vb01{
|
||||
Vector3 pos,norm;
|
||||
Vector2 texCoords;
|
||||
};
|
||||
|
||||
Mesh(Vertex*,unsigned int*,int);
|
||||
~Mesh();
|
||||
virtual void update();
|
||||
@@ -28,6 +29,8 @@ namespace vb01{
|
||||
inline std::vector<Mesh*>& getMeshes(){return meshes;}
|
||||
inline bool isCastShadow(){return castShadow;}
|
||||
inline int getNumVerts(){return 3*numTris;}
|
||||
inline Vertex* getVerts(){return vertices;}
|
||||
inline unsigned int* getIndices(){return indices;}
|
||||
private:
|
||||
Material *material=nullptr;
|
||||
Node *node=nullptr;
|
||||
|
||||
@@ -120,4 +120,59 @@ namespace vb01{
|
||||
descendants.push_back(node->getChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
Node::Transform Node::getWorldTransform(){
|
||||
Transform t;
|
||||
Vector3 scale=Vector3::VEC_IJK;
|
||||
Quaternion orient=Quaternion::QUAT_W;
|
||||
Vector3 origin=Vector3::VEC_ZERO,axis[]={Vector3::VEC_I,Vector3::VEC_J,Vector3::VEC_K};
|
||||
vector<Node*> ancestors;
|
||||
ancestors.push_back(this);
|
||||
Node *parent=this->getParent();
|
||||
while(parent){
|
||||
ancestors.push_back(parent);
|
||||
parent=parent->getParent();
|
||||
}
|
||||
while(!ancestors.empty()){
|
||||
int id=ancestors.size()-1;
|
||||
Quaternion o=ancestors[id]->getOrientation();
|
||||
Vector3 p=ancestors[id]->getPosition(),s=ancestors[id]->getScale();
|
||||
origin=origin+axis[0]*p.x*s.x+axis[1]*p.y*s.y+axis[2]*p.z*s.z;
|
||||
orient=o*orient;
|
||||
scale=s;
|
||||
for(int i=0;i<3;i++)
|
||||
axis[i]=orient*axis[i];
|
||||
ancestors.pop_back();
|
||||
}
|
||||
|
||||
t.position=origin,t.orientation=orient,t.scale=scale;
|
||||
return t;
|
||||
}
|
||||
|
||||
Vector3 Node::getLocalAxis(int i){
|
||||
Transform t;
|
||||
Vector3 pos=Vector3::VEC_ZERO,scale=Vector3::VEC_IJK;
|
||||
Quaternion orient=Quaternion::QUAT_W;
|
||||
Vector3 origin=Vector3::VEC_ZERO,axis[]={Vector3::VEC_I,Vector3::VEC_J,Vector3::VEC_K};
|
||||
vector<Node*> ancestors;
|
||||
ancestors.push_back(this);
|
||||
Node *parent=this->getParent();
|
||||
while(parent){
|
||||
ancestors.push_back(parent);
|
||||
parent=parent->getParent();
|
||||
}
|
||||
while(!ancestors.empty()){
|
||||
int id=ancestors.size()-1;
|
||||
Quaternion o=ancestors[id]->getOrientation();
|
||||
Vector3 p=ancestors[id]->getPosition(),s=ancestors[id]->getScale();
|
||||
origin=origin+axis[0]*p.x*s.x+axis[1]*p.y*s.y+axis[2]*p.z*s.z;
|
||||
orient=o*orient;
|
||||
scale=s;
|
||||
for(int i=0;i<3;i++)
|
||||
axis[i]=orient*axis[i];
|
||||
ancestors.pop_back();
|
||||
}
|
||||
|
||||
return axis[i];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,11 @@ namespace vb01{
|
||||
|
||||
class Node{
|
||||
public:
|
||||
struct Transform{
|
||||
Vector3 position,scale;
|
||||
Quaternion orientation;
|
||||
};
|
||||
|
||||
Node(Vector3=Vector3::VEC_ZERO,Quaternion=Quaternion::QUAT_W,Vector3=Vector3::VEC_IJK);
|
||||
~Node();
|
||||
void attachMesh(Mesh*);
|
||||
@@ -23,6 +28,12 @@ namespace vb01{
|
||||
void dettachChild(Node*);
|
||||
void addLight(Light*);
|
||||
void addText(Text*);
|
||||
Transform getWorldTransform();
|
||||
Vector3 getLocalAxis(int);
|
||||
inline Text* getText(int i){return texts[i];}
|
||||
inline Vector3 getWorldPosition(){return getWorldTransform().position;}
|
||||
inline Quaternion getWorldOrientation(){return getWorldTransform().orientation;}
|
||||
inline Vector3 getWorldScale(){return getWorldTransform().scale;}
|
||||
inline std::vector<Mesh*>& getMeshes(){return meshes;}
|
||||
inline Node* getParent(){return parent;}
|
||||
inline void setParent(Node *par){this->parent=par;}
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ namespace vb01{
|
||||
}
|
||||
inline vb01::Vector3 operator* (vb01::Vector3 v){
|
||||
Quaternion vQuat=(*this)*Quaternion(0,v.x,v.y,v.z)*recip();
|
||||
return Vector3(vQuat.x,vQuat.y,vQuat.z).norm();
|
||||
return Vector3(vQuat.x,vQuat.y,vQuat.z);
|
||||
}
|
||||
inline vb01::Quaternion fromAngle(float angle, Vector3 axis){
|
||||
return Quaternion(cos(angle/2),axis.x*sin(angle/2),axis.y*sin(angle/2),axis.z*sin(angle/2));
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#include<algorithm>
|
||||
#include"ray.h"
|
||||
#include"mesh.h"
|
||||
#include"node.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace vb01{
|
||||
void retrieveCollisions(Vector3 rayPos, Vector3 rayDir,Node *node,std::vector<CollisionResult> &results, const float rayLength){
|
||||
Vector3 pos=node->getWorldPosition();
|
||||
Quaternion rot=node->getWorldOrientation();
|
||||
for(Mesh *m : node->getMeshes()){
|
||||
const int numVerts=m->getNumVerts();
|
||||
Mesh::Vertex *vertices=m->getVerts();
|
||||
u32 *indices=m->getIndices();
|
||||
|
||||
for(int i=0;i<numVerts/3;i++){
|
||||
Vector3 pointA=pos+rot*vertices[indices[i*3]].pos,pointB=pos+rot*vertices[indices[i*3+1]].pos,pointC=pos+rot*vertices[indices[i*3+2]].pos;
|
||||
Vector3 hypVec=pointA-rayPos;
|
||||
Vector3 perpVec=(pointB-pointA).cross(pointC-pointA);
|
||||
float a1=hypVec.norm().getAngleBetween(perpVec.norm());
|
||||
if(a1>PI/2){
|
||||
a1=PI-a1;
|
||||
perpVec=-perpVec;
|
||||
}
|
||||
float perpLine=hypVec.getLength()*cos(a1);
|
||||
float a2=perpVec.norm().getAngleBetween(rayDir.norm());
|
||||
if(a2<=PI/2){
|
||||
float distance=perpLine/cos(a2);
|
||||
if((distance<=rayLength&&rayLength!=.0)||rayLength==.0){
|
||||
Vector3 contactPoint=rayPos+rayDir.norm()*distance;
|
||||
float angleA=(pointB-pointA).norm().getAngleBetween((pointC-pointA).norm());
|
||||
float angleB=(pointA-pointB).norm().getAngleBetween((pointC-pointB).norm());
|
||||
float angleC=(pointB-pointC).norm().getAngleBetween((pointA-pointC).norm());
|
||||
Vector3 bisecAVec=((pointB-pointA)+(pointC-pointA));
|
||||
Vector3 bisecBVec=((pointA-pointB)+(pointC-pointB));
|
||||
Vector3 bisecCVec=((pointB-pointC)+(pointA-pointC));
|
||||
bool withinBisecA=(contactPoint-pointA).norm().getAngleBetween(bisecAVec.norm())<=angleA/2;
|
||||
bool withinBisecB=(contactPoint-pointB).norm().getAngleBetween(bisecBVec.norm())<=angleB/2;
|
||||
//bool withinBisecC=(contactPoint-pointC).norm().getAngleBetween(bisecCVec.norm())<=angleC/2;
|
||||
if(withinBisecA&&withinBisecB){
|
||||
CollisionResult result;
|
||||
result.pos=contactPoint;
|
||||
result.distance=distance;
|
||||
result.mesh=m;
|
||||
results.push_back(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(Node *c : node->getChildren())
|
||||
retrieveCollisions(rayPos,rayDir,c,results,rayLength);
|
||||
}
|
||||
|
||||
void sortResults(std::vector<CollisionResult> &results){
|
||||
for(int i=0;i<results.size();i++){
|
||||
for(int i2=i;i2<results.size();i2++)
|
||||
if(results[i].distance>results[i2].distance)
|
||||
swap(results[i],results[i2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include"vector.h"
|
||||
#include"util.h"
|
||||
#include<vector>
|
||||
|
||||
namespace vb01{
|
||||
class Node;
|
||||
class Mesh;
|
||||
|
||||
struct CollisionResult{
|
||||
Vector3 pos;
|
||||
float distance;
|
||||
Mesh *mesh=nullptr;
|
||||
};
|
||||
|
||||
void retrieveCollisions(Vector3,Vector3,Node*,std::vector<CollisionResult>&,const float=.0);
|
||||
void sortResults(std::vector<CollisionResult>&);
|
||||
}
|
||||
@@ -31,6 +31,7 @@ namespace vb01{
|
||||
this->z=z;
|
||||
}
|
||||
bool operator==(const Vector3 &v){return x==v.x&&y==v.y&&z==v.z;}
|
||||
Vector3 operator-(){return Vector3(-x,-y,-z);}
|
||||
Vector3 operator-(const Vector3 &v){return Vector3(x-v.x,y-v.y,z-v.z);}
|
||||
Vector3 operator+(const Vector3 &v){return Vector3(x+v.x,y+v.y,z+v.z);}
|
||||
template<typename T>Vector3 operator+(T s){return Vector3(x+s,y+s,z+s);}
|
||||
|
||||
Reference in New Issue
Block a user