Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vr movement and controls #31

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.os
project/bin/*
!project/bin/ProofGraphs.gdextension
!project/Meshes/cone.obj
venv
# Godot 4+ specific ignores
.godot/
191 changes: 139 additions & 52 deletions extension/vrproofgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ LogNode::LogNode(){
justification = "";
HashSet<LogNode*> logParents;
HashSet<LogNode*> logChildren;

}

void LogNode::setID(int nodeID){
Expand Down Expand Up @@ -54,19 +53,17 @@ void LogNode::setData(String newData){
newText->set_mesh(letters);
letters->TextMesh::set_text(newData);
StandardMaterial3D* skin = memnew(StandardMaterial3D);
//skin->set_emission(Color(1,1,1,1));
//skin->set_emission_energy_multiplier(8);
//skin->set_emission_operator(BaseMaterial3D::EMISSION_OP_MULTIPLY);
//skin->set_emission_intensity(2);
newText->set_material_overlay(skin);

newText->global_scale(Vector3(12,12,5));
newText->set_position(Vector3(0,.4,0));
newText->global_scale(Vector3(1.2,1.2,.5));
newText->set_position(Vector3(0,.04,0));

MeshInstance3D* oldBox = (MeshInstance3D*) get_node_or_null("box");
if (newData.length() > 9){
MeshInstance3D* oldBox = (MeshInstance3D*) get_node_or_null("box");
//Each additional letter adds more than 1 scale unit
oldBox->set_scale(Vector3(10+(newData.length()-10)*1.15,5,2));
oldBox->set_scale(Vector3(1+(newData.length()-10)*.135,.5,.2));
}
else {
oldBox->set_scale(Vector3(1.0,.5,.2));
}
}

Expand All @@ -79,6 +76,7 @@ bool LogNode::isChild(LogNode* potentialChild){
}
}

// Old version, not used
String LogNode::getParentRep(){
String value = "(";
for(LogNode* i : logParents){
Expand All @@ -95,6 +93,7 @@ String LogNode::getParentRep(){
return value;
}

//Old version, not used
void LogNode::setParentRep(){
Node* oldText = get_node_or_null("Parents");
if(oldText != NULL){
Expand All @@ -107,8 +106,65 @@ void LogNode::setParentRep(){
TextMesh* letters = memnew(TextMesh);
newText->set_mesh(letters);
letters->TextMesh::set_text(this->getParentRep());
newText->global_scale(Vector3(8,8,5));
newText->set_position(Vector3(0,-1.5,0));
newText->global_scale(Vector3(.8,.8,.5));
newText->set_position(Vector3(0,-.15,0));
}

// Set used to avoid duplicates
// Finds all ancestor node IDs
// Cycle check should keep it from running infinitely
void LogNode::assumeFind(LogNode* currentNode, HashSet<int>* tempAssume){
for (LogNode* parent : currentNode->logParents){
if (parent->justification == "assume"){
tempAssume->insert(parent->getID());
}
assumeFind(parent, tempAssume);
}
}

// Converts the set to a string for mesh representation
String LogNode::assumeString(HashSet<int>* assume){
String value = "(";
for(int i : *(assume)){
value = value + String::num_uint64(i);
value = value + ",";
}
if (value.length() > 1){
value = value.left(value.length() - 1);
value = value + ")";
}
else {
value = "";
}
return value;
}

void LogNode::setAssumeRep(){
HashSet<int> tempAssume;

assumeFind(this, &tempAssume);
String words = assumeString(&tempAssume);

Node* oldText = get_node_or_null("Parents");
if(oldText != NULL){
remove_child(oldText);
oldText->queue_free();
}
MeshInstance3D* newText = memnew(MeshInstance3D);
newText->set_name("Parents");
add_child(newText);
TextMesh* letters = memnew(TextMesh);
newText->set_mesh(letters);
letters->TextMesh::set_text(words);
newText->global_scale(Vector3(.8,.8,.5));
newText->set_position(Vector3(0,-.15,0));
}

void LogNode::assumeCascade(){
for (LogNode* child : this->logChildren){
child->setAssumeRep();
child->assumeCascade();
}
}

void LogNode::setJustification(String code, String symbol){
Expand All @@ -126,11 +182,41 @@ void LogNode::setJustification(String code, String symbol){
TextMesh* letters = memnew(TextMesh);
newText->set_mesh(letters);
letters->TextMesh::set_text(symbol);
newText->global_scale(Vector3(12,12,5));
newText->set_position(Vector3(0,3.85,0));
newText->global_scale(Vector3(1.2,1.2,.5));
newText->set_position(Vector3(0,.385,0));

MeshInstance3D* oldBox = (MeshInstance3D*) get_node_or_null("justBox");
oldBox->set_scale(Vector3(symbol.length()*1.15+1,2.25,2));
oldBox->set_scale(Vector3((symbol.length()*.115)+.1,.225,.2));

this->assumeCascade();
}

bool LogNode::findParentless(LogNode* targetNode, HashSet<int> found){
// If a node has no parents it is not part of a cycle
if(targetNode->logParents.is_empty()){
return 0;
}
// If the node is revisited, we are in a cycle
if (found.find(targetNode->getID()) != found.end()){
return 1;
}
found.insert(targetNode->getID());
bool cycleFlag = 0;
// Recursive DFS through parents to check for cycles
for (LogNode* parent : targetNode->logParents){
cycleFlag = findParentless(parent, found);
if (cycleFlag == 1){
return cycleFlag;
}
}
return cycleFlag;
}

bool LogNode::dfsCheck(){
bool cycleFlag = 0;
HashSet<int> found;
cycleFlag = findParentless(this, found);
return cycleFlag;
}


Expand Down Expand Up @@ -176,7 +262,7 @@ void VRProofGraph::addNode(Vector3 position){
newNode->add_child(box);
box->set_mesh(shape);
box->set_material_override(skin);
box->set_scale(Vector3(10,5,2));
box->set_scale(Vector3(1.0,.5,.2));
skin->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA);
skin->set_albedo(Color(0.5, 0.75, 0.75, 0.25));

Expand All @@ -187,8 +273,8 @@ void VRProofGraph::addNode(Vector3 position){
TextMesh* numbers = memnew(TextMesh);
idText->set_mesh(numbers);
numbers->TextMesh::set_text("ID: " + String::num_int64(newNode->getID()));
idText->set_position(Vector3(-3.25, 1.9, 0));
idText->set_scale(Vector3(8,8,5));
idText->set_position(Vector3(-.325, .19, 0));
idText->set_scale(Vector3(.8,.8,.5));

//Physics collider for ray casts

Expand All @@ -199,7 +285,7 @@ void VRProofGraph::addNode(Vector3 position){
newNode->add_child(nodeCollider);
nodeCollider->add_child(physBody);
physBody->set_shape(physBox);
physBody->set_scale(Vector3(10,5,2));
physBody->set_scale(Vector3(1.0,.5,.2));

//Create box mesh for justification
MeshInstance3D* justBox = memnew(MeshInstance3D);
Expand All @@ -209,57 +295,64 @@ void VRProofGraph::addNode(Vector3 position){
newNode->add_child(justBox);
justBox->set_mesh(justShape);
justBox->set_material_override(justSkin);
justBox->set_scale(Vector3(3,2.25,2));
justBox->set_scale(Vector3(.3,.225,.2));
justSkin->set_transparency(BaseMaterial3D::TRANSPARENCY_ALPHA);
justSkin->set_albedo(Color(0.5, 0.75, 0.75, 0.25));
justBox->set_position(Vector3(0,3.75,0));
justBox->set_position(Vector3(0,.375,.0));
}

void VRProofGraph::edgeSetter(LogNode* start, LogNode* end, MeshInstance3D* workingEdge){
Vector3 topBoxOffset = Vector3(0,1.25,0);
Vector3 bottomBoxOffset = Vector3(0,2.5,0);
Vector3 topBoxOffset = Vector3(0,.475,0);
Vector3 bottomBoxOffset = Vector3(0,.25,0);
Vector3 sPos = start->get_global_position();
Vector3 ePos = end->get_global_position() + Vector3(0,3.75,0);
Vector3 ePos = end->get_global_position();
Vector3 startOffset = Vector3(0,0,0);
Vector3 endOffset = Vector3(0,0,0);
if (sPos.y > ePos.y){
startOffset = sPos - bottomBoxOffset;
endOffset = ePos + topBoxOffset;
}
else{
startOffset = sPos - topBoxOffset;
endOffset = ePos + bottomBoxOffset;
startOffset = sPos + topBoxOffset;
endOffset = ePos - bottomBoxOffset;
}

Vector3 location = (startOffset+endOffset)/2;
double lineLength = (startOffset-endOffset).length();

workingEdge->set_scale(Vector3(0.3,0.3,lineLength));
workingEdge->set_scale(Vector3(0.03,0.03,lineLength));
// Sets both global position and facing direction
workingEdge->look_at_from_position(location, endOffset, Vector3(0,1,0), true);
}


void VRProofGraph::addEdge(LogNode* start, LogNode* end){

if (nodeMap[start->getID()]->logChildren.find(nodeMap[end->getID()]) != nodeMap[start->getID()]->logChildren.end()
|| nodeMap[end->getID()]->logParents.find(nodeMap[start->getID()]) != nodeMap[end->getID()]->logParents.end()){
}
else {
//Logic
nodeMap[start->getID()]->logChildren.insert(nodeMap[end->getID()]);
nodeMap[end->getID()]->logParents.insert(nodeMap[start->getID()]);

//Meshes
MeshInstance3D* lineMesh = memnew(MeshInstance3D);
BoxMesh* shape = memnew(BoxMesh);
lineMesh->set_mesh(shape);
lineMesh->set_name(String::num_int64(start->getID())+ String::num_int64(end->getID()));

start->add_child(lineMesh);

edgeSetter(start, end, lineMesh);
end->setParentRep();
nodeMap[start->getID()]->logChildren.insert(nodeMap[end->getID()]);
nodeMap[end->getID()]->logParents.insert(nodeMap[start->getID()]);

if (start->dfsCheck()){
nodeMap[start->getID()]->logChildren.erase(nodeMap[end->getID()]);
nodeMap[end->getID()]->logParents.erase(nodeMap[start->getID()]);
}

else{
//Meshes
MeshInstance3D* lineMesh = memnew(MeshInstance3D);
BoxMesh* shape = memnew(BoxMesh);
lineMesh->set_mesh(shape);
lineMesh->set_name(String::num_int64(start->getID())+ String::num_int64(end->getID()));

start->add_child(lineMesh);

edgeSetter(start, end, lineMesh);
end->setAssumeRep();
end->assumeCascade();
}
}
}

Expand All @@ -274,9 +367,9 @@ void VRProofGraph::removeEdge(LogNode* start, LogNode* end){
Node* badEdge = get_node_internal(String::num_int64(start->getID()) + "/" +String::num_int64(start->getID())+String::num_int64(end->getID()));
start->remove_child(badEdge);
badEdge->queue_free();
end->setParentRep();
end->setAssumeRep();
end->assumeCascade();
}

}

// Needs checks for node validity
Expand All @@ -291,10 +384,12 @@ void VRProofGraph::removeNode(LogNode* badNode){
badEdge->queue_free();
}

badNode->assumeCascade();

// Logic remove pointers of children to badNode, updates parent rep
for (LogNode* i : badNode->logChildren){
i->logParents.erase(badNode);
i->setParentRep();
i->setAssumeRep();
}

nodeMap.erase(badNode->getID());
Expand Down Expand Up @@ -337,13 +432,6 @@ void VRProofGraph::updateEdges(LogNode* updateNode){
}
}

void VRProofGraph::boxLookAtPlayer(){
Node3D* playerNode = (Node3D*) get_parent()->get_node_or_null("PlayerCharacter/CharacterBody3D/Neck/Camera3D");
for (KeyValue<int, LogNode*> i : nodeMap){
i.value->look_at(playerNode->get_global_position(), Vector3(0,-1,0));
}
}

void VRProofGraph::_bind_methods(){
ClassDB::bind_method(D_METHOD("addNode", "newNode"), &VRProofGraph::addNode);
ClassDB::bind_method(D_METHOD("addEdge", "start", "end"), &VRProofGraph::addEdge);
Expand All @@ -352,5 +440,4 @@ void VRProofGraph::_bind_methods(){
ClassDB::bind_method(D_METHOD("getNodeCount"), &VRProofGraph::getNodeCount);
ClassDB::bind_method(D_METHOD("getData", "nodeID"), &VRProofGraph::getNodeData);
ClassDB::bind_method(D_METHOD("updateEdges"), &VRProofGraph::updateEdges);
ClassDB::bind_method(D_METHOD("boxLookAtPlayer"), &VRProofGraph::boxLookAtPlayer);
}
28 changes: 17 additions & 11 deletions extension/vrproofgraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,25 +34,31 @@ class LogNode : public Node3D{
bool isChild(LogNode* potentialChild);
String getParentRep();
void setParentRep();
void assumeFind(LogNode* currentNode, HashSet<int>* tempAssume);
String assumeString(HashSet<int>* assume);
void setAssumeRep();
void assumeCascade();
void setJustification(String code, String symbol);
bool findParentless(LogNode* targetNode, HashSet<int> found);
bool dfsCheck();


protected:
static void _bind_methods();
};

class VRProofGraph : public Node{
GDCLASS(VRProofGraph, Node)
class VRProofGraph : public Node{
GDCLASS(VRProofGraph, Node)

private:
int nodeCount;
int nodeIDCount;
HashMap<int, LogNode*> nodeMap;
public:
// Constructor, creates empty proof graph
VRProofGraph();
~VRProofGraph();
private:
int nodeCount;
int nodeIDCount;
HashMap<int, LogNode*> nodeMap;
public:

// Constructor, creates empty proof graph
VRProofGraph();
~VRProofGraph();

//void addNode(Vector3 location, int data);
void addNode(Vector3 position);
Expand Down
Loading
Loading