Fix selection of second htc controller

Fix Atoms+fixedatoms+haptics bug
Add encyclopediajson=json option, add analyticsjson option.
parent 6d53da97
......@@ -78,8 +78,9 @@ const char * loadConfigFileErrors[] =
"markercolours with no previous correct timesteps parameter", //-18
"Error reading atomcolour", // -19
"Error loading xyz file, add 100 to see the error",//<-100
"Error loading cube file, add 100 to see the error",//<-200
"Error loading json file, add 200 to see the error",//<-300
"Error loading cube file, add 200 to see the error",//<-200
"Error loading encyclopedia json file, add 300 to see the error",//<-300
"Error loading analytics json file, add 400 to see the error",//<-400
};
void updateTIMESTEPS (int timesteps)
......@@ -180,6 +181,7 @@ int loadConfigFile(const char * f)
screenshotdownscaling=1;
hapticFeedback=false;
showcontrollers=false;
inv_abc_init=false;
//
FILE *F = fopen(f, "r");
if (F == 0)
......@@ -328,7 +330,7 @@ int loadConfigFile(const char * f)
}
has_abc = true;
}
else if (!strcmp(s, "json")) {
else if (!strcmp(s, "json") || !strcmp (s, "encyclopediajson")) {
r=readString(F, s);
if (r!=0)
return -14;
......@@ -344,7 +346,24 @@ int loadConfigFile(const char * f)
numClonedAtoms=clonedAtoms[0].size()/4;
has_abc=true;
updateTIMESTEPS (timesteps);
}
}
else if (!strcmp(s, "analyticsjson")) {
r = readString(F, s);
if (r != 0)
return -14;
char file[256];
sprintf(file, "%s%s", PATH, s);
fixFile(file);
int e;
int timesteps;
//rgh fixme, we know only one
e = readAtomsAnalyticsJson(file, &numAtoms, &timesteps, &atoms, abc, &clonedAtoms);
if (e<0)
return e - 400;
numClonedAtoms = clonedAtoms[0].size() / 4;
has_abc = true;
updateTIMESTEPS(timesteps);
}
else if (!strcmp(s, "baseurl")) {
r=readString (F, base_url);
if (r!=0)
......
......@@ -2,6 +2,7 @@
#include <vector>
#include <math.h>
#include <stdint.h>
#include "MyGL.h"
#include "eprintf.h"
......
......@@ -24,6 +24,11 @@ const char * TMPDIR;//filled by main
//="/storage/540E-1AE2/";
#endif
bool inv_abc_init=false;
float inv_abc[3][3];
const char * const atomNames[] =
{
......@@ -493,7 +498,7 @@ return readAtomsJson (cmd, numatoms, timesteps, pos, abc, clonedAtoms, token);
bool isAlmostZero(float coordinate)
{
return (coordinate < 1E-5);
return (fabs(coordinate) < 1E-5);
}
void add (std::vector<float> *v, float x, float y, float z, float a)
......@@ -504,6 +509,71 @@ void add (std::vector<float> *v, float x, float y, float z, float a)
v->push_back(a);
}
const char * readAtomsAnalyticsJsonErrors[] = {
"All Ok",//0
"Could not open file", //-1
"atom_species not in json", //-2
"json parse error or no atom_positions", //-3
"lattice_vectors not in json", //-4
};
int readAtomsAnalyticsJson(const char *const f, int **numatoms, int *timesteps, float ***pos, float abc[3][3],
std::vector<float>** clonedAtoms)
{
float tmppos[3];
FILE *fp = fopen(f, "r");
if (fp == 0) {
eprintf("readAtomsAnalyticsJson, could not open file %s", f);
return -1;
}
char readBuffer[65536];
rapidjson::FileReadStream is(fp, readBuffer, sizeof(readBuffer));
rapidjson::Document json;
json.ParseStream(is);
fclose(fp);
*timesteps = 1;
*pos = new float*[*timesteps];
*numatoms = new int[*timesteps];
*clonedAtoms=new std::vector<float>[*timesteps];
if (!json.HasParseError() && json.HasMember("atom_positions")) {
if (json.HasMember("lattice_vectors")) {
const rapidjson::GenericValue<rapidjson::UTF8<> > &lv = json["lattice_vectors"];
const rapidjson::GenericValue<rapidjson::UTF8<> > &flatdata = lv["flatData"];
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
abc[i][j]=flatdata[i*3+j].GetFloat()*1e10; // meter -> aangstrom
} else return (-4);
const rapidjson::GenericValue<rapidjson::UTF8<> > &result = json["atom_positions"];
if (!result.HasMember("shape"))
return (-1);
const rapidjson::GenericValue<rapidjson::UTF8<> > &shape = result["shape"]; //[numatoms, 3]
**numatoms = shape[0].GetInt();
(*pos)[0] = new float[**numatoms * 4];
if (json.HasMember("atom_species")) {
const rapidjson::GenericValue<rapidjson::UTF8<> > &results = json["atom_species"];
for (int i = 0; i < **numatoms ; i++)
(*pos)[0][i*4+3]=results[i].GetInt()-1;
//atoms are stored in space coordinates, in meters
//rgh FIXME: disable cloned atoms for now
const rapidjson::GenericValue<rapidjson::UTF8<> > &flatdata = result["flatData"];
for (int i = 0; i < **numatoms ; i++) {
for (int j=0;j<3;j++)
(*pos)[0][i*4+j] = flatdata[i*3+j].GetFloat()*1e10; //we store them in aangstrom
CloneSpatialAtoms((*pos)[0], (*pos)[0][3], *clonedAtoms);
}
}
else return (-2);
}
else return (-3);
TransformAtoms(*clonedAtoms, abc);
return 0;
}
int readAtomsJson (const char *const f, int **numatoms, int *timesteps, float ***pos, float abc[3][3],
std::vector<float>** clonedAtoms, const char *const token)
{
......@@ -600,13 +670,14 @@ int readAtomsJson (const char *const f, int **numatoms, int *timesteps, float **
(**pos)[4*i+s]=tmppos[0]*abc[0][s]+tmppos[1]*abc[1][s]+tmppos[2]*abc[2][s];
}
TransformAtoms(*clonedAtoms, abc);
}
TransformAtoms(*clonedAtoms, abc);
//eprintf ("readAtomsJson, end");
return 0;
}
//from abc coordinates to spatial coordinates
void TransformAtoms(std::vector<float>* clonedAtoms, const float abc[3][3])
{
float tmppos[3];
......@@ -618,6 +689,57 @@ void TransformAtoms(std::vector<float>* clonedAtoms, const float abc[3][3])
}
}
//returns false if abc is not an invertible matrix (should not happen)
bool CloneSpatialAtoms (float tmppos[3], float k, std::vector<float>* clonedAtoms)
{ //move atoms to abc coordinates, then Clone()
if (!inv_abc_init) {
inv_abc_init=true;
//Contains code from OpenVR samples/shared/Matrices.cpp under the
//BSD 3-clause "New" or "Revised" License
//https://github.com/ValveSoftware/openvr/blob/master/LICENSE
float tmp[9];
float determinant;
tmp[0] = abc[1][1] * abc[2][2] - abc[1][2] * abc[2][1];
tmp[1] = abc[0][2] * abc[2][1] - abc[0][1] * abc[2][2];
tmp[2] = abc[0][1] * abc[1][2] - abc[0][2] * abc[1][1];
tmp[3] = abc[1][2] * abc[2][0] - abc[1][0] * abc[2][2];
tmp[4] = abc[0][0] * abc[2][2] - abc[0][2] * abc[2][0];
tmp[5] = abc[0][2] * abc[1][0] - abc[0][0] * abc[1][2];
tmp[6] = abc[1][0] * abc[2][1] - abc[1][1] * abc[2][0];
tmp[7] = abc[0][1] * abc[2][0] - abc[0][0] * abc[2][1];
tmp[8] = abc[0][0] * abc[1][1] - abc[0][1] * abc[1][0];
// check determinant if it is 0
determinant = abc[0][0] * tmp[0] + abc[0][1] * tmp[3] + abc[0][2] * tmp[6];
if(fabs(determinant) <= 1e-5)
{
return false; // cannot inverse, make it idenety matrix
}
// divide by the determinant
float invDeterminant = 1.0f / determinant;
inv_abc[0][0] = invDeterminant * tmp[0];
inv_abc[0][1] = invDeterminant * tmp[1];
inv_abc[0][2] = invDeterminant * tmp[2];
inv_abc[1][0] = invDeterminant * tmp[3];
inv_abc[1][1] = invDeterminant * tmp[4];
inv_abc[1][2] = invDeterminant * tmp[5];
inv_abc[2][0] = invDeterminant * tmp[6];
inv_abc[2][1] = invDeterminant * tmp[7];
inv_abc[2][2] = invDeterminant * tmp[8];
}
float t[3];
for (int s=0;s<3;s++)
t[s]=tmppos[0]*inv_abc[0][s]+tmppos[1]*inv_abc[1][s]+tmppos[2]*inv_abc[2][s];
Clone (t, k, clonedAtoms);
return true;
}
//tmppos in abc coordinates
void Clone (float tmppos[3], float k, std::vector<float>* clonedAtoms)
{
bool iaz[3];
......
......@@ -16,6 +16,8 @@ extern const char * TMPDIR;
int readAtomsXYZ(const char *const file, int **numatoms, int *timesteps, float ***pos);
int readAtomsCube(const char *const file, int **numatoms, int *timesteps, float ***pos);
int readAtomsJson (const char *const file, int **numatoms, int *timesteps, float ***pos, float abc[3][3], std::vector<float>** clonedAtoms, const char *const token=0);
int readAtomsAnalyticsJson(const char *const f, int **numatoms, int *timesteps, float ***pos, float abc[3][3],
std::vector<float>** clonedAtoms);
int readAtomsJsonURL (const char *const f, int **numatoms, int *timesteps, float ***pos, float abc[3][3], std::vector<float>** clonedAtoms, const char *const token=0);
#if defined(WIN32) || defined(CAVE)
int readAtomsJsonURLwget (const char *const f, int **numatoms, int *timesteps, float ***pos, float abc[3][3], std::vector<float>** clonedAtoms, const char *const token=0);
......@@ -28,6 +30,7 @@ const float MISSINGB=1.f;
extern const char * readAtomsXYZErrors[];
extern const char * readAtomsCubeErrors[];
extern const char * readAtomsJsonErrors[];
extern const char * readAtomsAnalyticsJsonErrors[];
float atomRadius (int i);
int findAtom(const char *const s);
......@@ -35,6 +38,10 @@ int findAtom(const char *const s);
//internal functions
void discardline (FILE *F);
void Clone (float tmppos[3], float k, std::vector<float>* clonedAtoms);
bool CloneSpatialAtoms (float tmppos[3], float k, std::vector<float>* clonedAtoms);
void TransformAtoms(std::vector<float>* clonedAtoms, const float abc[3][3]);
extern bool inv_abc_init;
extern float inv_abc[3][3];
#endif //__ATOMS_H
......@@ -17,7 +17,7 @@
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <winsock2.h>
......@@ -955,7 +955,7 @@ bool CMainApplication::HandleInput()
buttonPressed[1][unDevice] = true;
if (firstdevice == -1)
firstdevice = unDevice;
else if(seconddevice==-1)
else if(unDevice !=firstdevice && seconddevice==-1)
seconddevice=unDevice;
if (firstdevice==unDevice)
......@@ -974,7 +974,7 @@ bool CMainApplication::HandleInput()
buttonPressed[0][unDevice] = true;
if (firstdevice == -1)
firstdevice = unDevice;
else if(seconddevice==-1)
else if(unDevice !=firstdevice && seconddevice==-1)
seconddevice=unDevice;
if (unDevice == firstdevice) {
......@@ -993,6 +993,8 @@ bool CMainApplication::HandleInput()
{
if (firstdevice == -1)
firstdevice = unDevice;
else if (unDevice !=firstdevice && seconddevice==-1)
seconddevice=unDevice;
if (unDevice == firstdevice) {
Matrix4 tmp = m_mat4HMDPose;
UserPosition += tmp.invert()*Vector3(0, 0, speed);
......@@ -1087,23 +1089,30 @@ void CMainApplication::HapticFeedback(){
//-----------------------------------------------------------------------------
void CMainApplication::HapticFeedback(int device)
{
if (!numAtoms)
return;
if (device!=-1) {
vr::VRControllerState_t cs;
vr::TrackedDevicePose_t dp;
m_pHMD->GetControllerStateWithPose( vr::TrackingUniverseStanding, device, &cs, &dp );
if (dp.bPoseIsValid) {
int mycurrentset;
if (fixedAtoms)
mycurrentset=0;
else
mycurrentset=currentset;
vr::HmdMatrix34_t mat=dp.mDeviceToAbsoluteTracking;
Vector3 controllerPos(mat.m[0][3], mat.m[1][3],mat.m[2][3]);
int atomsInTimestep;
if (currentset==0)
if (mycurrentset==0)
atomsInTimestep=numAtoms[0];
else
atomsInTimestep=numAtoms[currentset]-numAtoms[currentset-1];
atomsInTimestep=numAtoms[mycurrentset]-numAtoms[mycurrentset-1];
for (int i=0;i<atomsInTimestep;i++) {
float atomr=atomRadius(atoms[currentset][i*4+3]);
float atomr=atomRadius(static_cast<int>(atoms[mycurrentset][i*4+3]));
//Vector3 posatom(atoms[currentset][i*4+0], atoms[currentset][i*4+1], atoms[currentset][i*4+2]);
Vector3 posatom(atoms[currentset][i*4+0], atoms[currentset][i*4+2], atoms[currentset][i*4+1]); //y/z flipped
Vector3 posatom(atoms[mycurrentset][i*4+0], atoms[mycurrentset][i*4+2], atoms[mycurrentset][i*4+1]); //y/z flipped
int p[3];
for (p[0]=0;p[0]<std::max(1,repetitions[0]);(p[0])++)
for (p[1]=0;p[1]<std::max(1,repetitions[1]);(p[1])++)
......@@ -1123,11 +1132,11 @@ void CMainApplication::HapticFeedback(int device)
}
}
//now cloned atoms
if (currentset==0 && clonedAtoms) {
if (mycurrentset==0 && clonedAtoms) {
Vector3 up(-UserPosition.x, -UserPosition.y, UserPosition.z);
for (int i=0;i<numClonedAtoms;i++) {
float atomr=atomRadius(clonedAtoms[currentset][i*4+3]);
Vector3 posatom(clonedAtoms[currentset][i*4+0], clonedAtoms[currentset][i*4+2], clonedAtoms[currentset][i*4+1]);
float atomr=atomRadius(static_cast<int>(clonedAtoms[mycurrentset][i*4+3]));
Vector3 posatom(clonedAtoms[mycurrentset][i*4+0], clonedAtoms[mycurrentset][i*4+2], clonedAtoms[mycurrentset][i*4+1]);
Vector3 pos=posatom-up;
pos.z=-pos.z;
float l=(pos - controllerPos).length();
......@@ -1601,7 +1610,7 @@ void CMainApplication::SetupIsosurfaces()
//matFinal.translate(translations[p%ISOS][0]+cubetrans[0], translations[p%ISOS][1]+cubetrans[1], translations[p%ISOS][2]+cubetrans[2]);
Matrix4 matcubetrans, mvs;
if (voxelSize[0]!=-1) {
mvs.scale(1.0 / (double)voxelSize[0], 1.0 / (double)voxelSize[1], 1.0 / (double)voxelSize[2]);
mvs.scale(1.0f / (float)voxelSize[0], 1.0f / (float)voxelSize[1], 1.0f / (float)voxelSize[2]);
matcubetrans.translate(cubetrans[0], cubetrans[1], cubetrans[2]); //angstrom
//if abc, in abc coordinates
/*Matrix4 abcm (abc[0][0], abc[1][0], abc[2][0], 0,
......@@ -2958,7 +2967,10 @@ int main(int argc, char *argv[])
MessageBoxA(0, readAtomsXYZErrors[-r-100], "XYZ file reading error", 0);
else if (-300<r)
MessageBoxA(0, readAtomsCubeErrors[-r-200], "Cube file reading error", 0);
else MessageBoxA(0, readAtomsJsonErrors[-r-300], "Json reading error", 0);
else if (-400<r)
MessageBoxA(0, readAtomsJsonErrors[-r-300], "Encyclopedia Json reading error", 0);
else
MessageBoxA(0, readAtomsAnalyticsJsonErrors[-r-400], "Analytics Json reading error", 0);
return -100+r;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment