//_________________________________________________________
//squareq.h
#include "headers.h"
class squareq{
public:
squareq();
void render(ConstantBuffer &cb);
void movef(float x, float y, float z);
void scalef(float x, float y, float z);
void rotatef(char dir, float ang);
vec::fixed<4> collision(squareq tester);
fmat::fixed<4,4> rotation;
fmat::fixed<4,4> translation;
fmat::fixed<4,4> scaling;
fmat::fixed<4,4> world;
float ex[3];
fvec::fixed<4> A[3], S[3], C;
private:
SimpleVertex vertices[4];
};
//_________________________________________________________
//squareq.cpp
#include "headers.h"
extern XMMATRIX g_View;
extern XMMATRIX g_Projection;
extern ID3D11DeviceContext* g_pImmediateContext;
extern ID3D11Buffer* g_pConstantBuffer;
extern ID3D11VertexShader* g_pVertexShader;
extern ID3D11PixelShader* g_pPixelShader;
squareq::squareq(){
rotation.eye();
translation.eye();
scaling.eye();
S[0] << 1 << 0 << 0 << 0;
S[1] << 0 << 1 << 0 << 0;
S[2] << 0 << 0 << 1 << 0;
ex[0] = 1;
ex[1] = 1;
ex[2] = 0;
A[0] = S[0];
A[1] = S[1];
A[2] = S[2];
}
void squareq::render(ConstantBuffer &cb){
world = rotation * translation * scaling;
world = world.t();
int i, j;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
cb.mWorld[i][j] = world(i,j);
}
}
cb.mView = XMMatrixTranspose( g_View );
cb.mProjection = XMMatrixTranspose( g_Projection );
g_pImmediateContext->UpdateSubresource( g_pConstantBuffer, 0, NULL, &cb, 0, 0 );
g_pImmediateContext->DrawIndexed( 12, 0, 0 );
}
void squareq::movef(float x, float y, float z){
translation << 1 << 0 << 0 << 0 << endr
<< 0 << 1 << 0 << 0 << endr
<< 0 << 0 << 1 << 0 << endr
<< x << y << z << 1;
C(0) = x;
C(1) = y;
C(2) = z;
}
void squareq::rotatef(char dir, float ang){
if(dir == 'x'){
rotation << 1 << 0 << 0 << 0 << endr
<< 0 << cos(ang) << -sin(ang) << 0 << endr
<< 0 << sin(ang) << cos(ang) << 0 << endr
<< 0 << 0 << 0 << 1;
A[1] = rotation * S[1];
A[2] = rotation * S[2];
}
if(dir == 'y'){
rotation << cos(ang) << 0 << sin(ang) << 0 << endr
<< 0 << 1 << 0 << 0 << endr
<< -sin(ang) << 0 << cos(ang) << 0 << endr
<< 0 << 0 << 0 << 1;
A[0] = rotation * S[0];
A[2] = rotation * S[2];
dir = 'h';
}
if(dir == 'z'){
rotation << cos(ang) << -sin(ang) << 0 << 0 << endr
<< sin(ang) << cos(ang) << 0 << 0 << endr
<< 0 << 0 << 1 << 0 << endr
<< 0 << 0 << 0 << 1;
A[0] = rotation * S[0];
A[1] = rotation * S[1];
}
}
void squareq::scalef(float x, float y, float z){
scaling << x << 0 << 0 << 0 << endr
<< 0 << y << 0 << 0 << endr
<< 0 << 0 << z << 0 << endr
<< 0 << 0 << 0 << 1 << endr;
ex[0] = x;
ex[1] = y;
ex[2] = z;
}
bool collision(squareq sq1, squareq sq2){
int i, j, k, sign;
fvec::fixed<3> A[3], B[3], C0, C1;
for(i=0;i<3;i++){
C0(i) = sq1.C(i);
C1(i) = sq2.C(i);
for(j=0;j<3;j++){
A[i](j) = sq1.A[i](j);
B[i](j) = sq2.A[i](j);
}
}
float R = 0, R0 = 0, R1 = 0;
fvec::fixed<3> D = C1 - C0;
fvec::fixed<3> L;
for(j = 0;j<3;j++){
L = A[j];
R = abs(dot(L, D));
for(k=0;k<3;k++){
if(dot(L, A[k]) > 0)
sign = 1;
else if(dot(L, A[k]) == 0)
sign = 0;
else
sign = -1;
R0 = R0 + sq1.ex[k]*sign*dot(L,A[k]);
R1 = R1 + sq2.ex[k]*sign*dot(L,B[k]);
}
if(!(R > (R0 + R1)))
return true;
R0 = 0;
R1 = 0;
L = B[j];
R = abs(dot(L, D));
for(k=0;k<3;k++){
if(dot(L, A[k]) > 0)
sign = 1;
else if(dot(L, A[k]) == 0)
sign = 0;
else
sign = -1;
R0 = R0 + sq1.ex[k]*sign*dot(L,A[k]);
R1 = R1 + sq2.ex[k]*sign*dot(L,B[k]);
}
if(!(R > (R0 + R1)))
return true;
R0 = 0;
R1 = 0;
for(i=0;i<3;i++){
L = cross(A[j], B[i]);
R = abs(dot(L, D));
for(k=0;k<3;k++){
if(dot(L, A[k]) > 0)
sign = 1;
else if(dot(L, A[k]) == 0)
sign = 0;
else
sign = -1;
R0 = R0 + sq1.ex[k]*sign*dot(L,A[k]);
R1 = R1 + sq2.ex[k]*sign*dot(L,B[k]);
}
if(!(R > (R0 + R1)))
return true;
R0 = 0;
R1 = 0;
}
}
return false;
}