#VRML V2.0 utf8 EXTERNPROTO Layer3D [ eventIn MFNode addChildren eventIn MFNode removeChildren eventIn MFNode addChildrenLayer eventIn MFNode removeChildrenLayer exposedField SFVec3f bboxSize exposedField SFVec3f bboxCenter exposedField MFNode childrenLayer exposedField SFVec2f translation exposedField SFInt32 depth exposedField SFVec2f size exposedField SFNode background exposedField SFNode fog exposedField SFNode navigationInfo exposedField SFNode viewpoint exposedField MFNode children ] [ "urn:inet:blaxxun.com:node:Layer3D" "http://www.blaxxun.com/vrml/protos/nodes.wrl#Layer3D" "http://www.blaxxun.com/developer/contact/3d/vrml/demo/layer/nodes.wrl#Layer3D" ] EXTERNPROTO helpScreen [ eventIn SFBool help ]"music-dossier-helpScreen.wrl#BLACKBOARD" EXTERNPROTO QuestionMarkModel [ eventIn SFFloat transparency ]"models/buttonBar/questionmark/questionmark.wrl#QuestionMarkModel" EXTERNPROTO GuidedTourModel [ eventIn SFFloat transparency ]"models/buttonBar/guidedtour/guided_tour.wrl#ModelGuidedTourNode" EXTERNPROTO MainModel [ eventIn SFFloat transparency ]"models/buttonBar/main/main_button.wrl#ModelMainButtonNode" EXTERNPROTO GuidedTour[ eventOut SFString showNodeCG eventOut SFString showNodePG eventOut SFString exit eventOut SFString nodeTitle eventOut SFBool exitButtons eventOut SFBool selectMiddleWindow eventOut SFString text eventIn SFBool start eventOut SFBool MaxMiddleWindow eventOut SFBool minimizeWindow eventOut SFBool startInitiated eventOut SFBool playAudio eventOut SFBool exit3Dinstallation ]"music-dossier-GuidedTour.wrl#GuidedTour" PROTO QuestionMark[ eventOut SFBool clicked eventIn SFFloat setTransparency ]{ DEF questionMarkSwitch Switch { whichChoice 0 choice [ Group { children [ DEF QM_TS TouchSensor { isActive IS clicked } DEF questionMarkTransform Transform { scale 2 2 2 children [ DEF questionMarkModel QuestionMarkModel {} ] } ] } ] } DEF questionMarkScript Script { eventIn SFBool rollOver eventIn SFTime time eventOut SFFloat fraction_changed eventIn SFBool rotationEnabled eventIn SFFloat setTransparency IS setTransparency field SFTime previousTimeRotation 0 field SFFloat totalTimeRotation 10 field SFFloat beginTransparency 0 eventOut SFFloat transparency field SFTime beginTimeTransparency 0 field SFBool transparencyEffectEnabled FALSE field SFFloat totalTimeTransparency 2 eventOut SFInt32 whichchoice eventOut MFString rollOverText url "javascript: function initialize() { transparency = beginTransparency; } // rotate question mark if rotation is enabled or the question mark is rotated already // a transparency effect is used to make the question mark disappear when closing the concept graph function time(value) { if (rotationEnabled || fraction_changed > 0) { fraction_changed += (time - previousTimeRotation) / totalTimeRotation; if (fraction_changed > 1) fraction_changed = 0; previousTimeRotation = value; } // simple interpolation: // if enabled: // compute factor, what fraction of total interpolation time has been passed // = (currencttime - starttime)/ totalTime // if this factor < 1: compute the interpolated value // if this factor >= 1: stop the interpolation, set interpolated value to the end value if (transparencyEffectEnabled) { var factor = (value - beginTimeTransparency) / totalTimeTransparency; if (factor < 1) { transparency = factor * (setTransparency - beginTransparency) + beginTransparency; } else { transparency = setTransparency; transparencyEffectEnabled = false; if (setTransparency == 1) whichchoice = -1;//removes question mark from scene so it can not be clicked } } } function rotationEnabled(value,time) { if (value) previousTimeRotation = time; } function setTransparency (value,time) { whichchoice = 0; beginTimeTransparency = time; beginTransparency = transparency; transparencyEffectEnabled = true; } function rollOver(value){ if (value){ rollOverText = 'help'; } else{ rollOverText = ''; } } " } DEF rollOverHelpText Transform { # rollover text for the help button translation 1.5 0 0 children [ Shape { geometry DEF rolloverHelpText Text { string "" } } ] } DEF Timer TimeSensor { loop TRUE } DEF Rotator OrientationInterpolator { key [0, 0.25, 0.5, 0.75, 1] keyValue [ 0 1 0 0, 0 1 0 1.57, 0 1 0 3.14, 0 1 0 4.71, 0 1 0 6.28 ] } ROUTE QM_TS.isOver TO questionMarkScript.rollOver ROUTE questionMarkScript.rollOverText TO rolloverHelpText.string ROUTE Timer.time TO questionMarkScript.time ROUTE QM_TS.isOver TO questionMarkScript.rotationEnabled ROUTE questionMarkScript.fraction_changed TO Rotator.set_fraction ROUTE Rotator.value_changed TO questionMarkTransform.rotation ROUTE questionMarkScript.transparency TO questionMarkModel.transparency ROUTE questionMarkScript.whichchoice TO questionMarkSwitch.whichChoice } PROTO DescriptionTextImage [ #c eventIn SFNode infoObject exposedField SFVec3f translationName 10 -10 2 exposedField SFVec3f translationDescription 10 -11.5 2 exposedField SFVec3f translationImage -20 -12 2 ] { DEF timer TimeSensor { #voor 'smooth' transparent maken van de text na rollOut. enabled TRUE loop TRUE } DEF descriptionTextImageScript Script { # zorgt voor verwijderen van de descriptionBox bij overgang naar presentationGraph eventIn SFTime time eventIn SFNode infoObject IS infoObject eventOut MFString descriptionInBox eventOut MFString nameInBox eventOut MFString urlImageOut eventOut SFFloat transparency eventOut SFVec3f scalePreviewImage field SFFloat endTransparency 1 field SFNode timer USE timer field SFTime beginTime 0 field SFTime totalTime 1 field SFFloat beginTransparency 0 field SFBool enabled FALSE field MFString emptyImageURL ["images/empty.gif"] url"javascript: function initialize(){ transparency = 1; scalePreviewImage = new SFVec3f(4,4,1); } function infoObject(value,time) { //invoked on mouse over event on item in concept graph if(value.ID != null) { // value != null does not work //print('over me:'+ value); nameInBox = invert(fitText(value.longName,33));//nameInBox is displayed buttom to top, so it will never overlap the description, because of that, the textlines have to be in inverted order descriptionInBox = fitText(value.description[0],40);// if (value.getType() == 'GroupNode' || value.getType() == 'TextItem' || value.getType() == 'Audio' || value.urlPreviewImage == null) { // do not use a image if node type = groupnode, textitem or if there is no previewimage urlImageOut = emptyImageURL; scalePreviewImage = new SFVec3f(4,4,1); } else { urlImageOut = value.urlPreviewImage; //correct size of preview image: resize display box to the correspond to the aspect ratio of the image if (value.widthPreviewImage/value.heightPreviewImage > 1) { scalePreviewImage = new SFVec3f(4,4 * value.heightPreviewImage/value.widthPreviewImage,1); } else scalePreviewImage = new SFVec3f(4 * value.widthPreviewImage/value.heightPreviewImage,4,1); } endTransparency = 0; } else { endTransparency = 1; } beginTime = time; beginTransparency = transparency; enabled = true; } // puts the lines of a MFString in the reverse order function invert(mfstring) { result = new MFString(); for (i = mfstring.length - 1; i >= 0; i --) { result[result.length] = mfstring[i]; } return result; } // creates a MFString that contains the text from text, on each line max 'size' characters // if possible, line ends are put behind whitespaces. function fitText(text,size) { var textToNode = new MFString(); var positionSpace = 0; var beginPosition = 0; var stop = false; while (!stop) { textLine = new String(''); if (text.length - beginPosition > size) { positionSpace = beginPosition + size; for (i = beginPosition; i < size + beginPosition; i ++) { if (text.charAt(i) == ' ') { positionSpace = i; } } } else positionSpace = text.length; for (i = beginPosition; i < positionSpace; i ++) { textLine += text.charAt(i); } textToNode[textToNode.length] = textLine; beginPosition = positionSpace + 1; if (beginPosition >= text.length) stop = true; } return textToNode; } function time(value){ if (enabled) { var factor = (value - beginTime)/totalTime; if (factor < 1) { transparency = factor * (endTransparency - beginTransparency) + beginTransparency; } else { transparency = endTransparency; enabled = false; } } } " } DEF NameSpace Transform { # longname dat bij roll over te zien is. translation IS translationName children [ Shape { appearance Appearance { texture DEF FONTname ImageTexture { url "groot.gif" } material DEF transparencyName Material { transparency 0 } } geometry DEF nameText Text { fontStyle FontStyle { family ["TEXTURE 0 255 16 16 0.5 0 0"] style "PLAIN" size 0.9 topToBottom FALSE } string "" } } ] } DEF DescriptionSpace Transform { # description text dat bij roll over te zien is. translation IS translationDescription children [ Shape { appearance Appearance { texture DEF FONTdescription ImageTexture { url "groot.gif" } material DEF transparencyDescription Material { transparency 0 } } geometry DEF descriptionText Text { fontStyle FontStyle { family ["TEXTURE 0 255 16 16 0.5 0 0"] style "PLAIN" size 0.7 } string "" } } ] } DEF ImageSpace Transform { #plaatje dat bij roll over te zien is. translation IS translationImage children [ Shape { appearance Appearance { material DEF transparencyImage Material { } texture DEF urlImage ImageTexture { url "" } } geometry Box { } } ] } ROUTE descriptionTextImageScript.transparency TO transparencyName.transparency ROUTE descriptionTextImageScript.transparency TO transparencyDescription.transparency ROUTE descriptionTextImageScript.transparency TO transparencyImage.transparency ROUTE timer.time TO descriptionTextImageScript.time ROUTE descriptionTextImageScript.nameInBox TO nameText.string ROUTE descriptionTextImageScript.descriptionInBox TO descriptionText.string ROUTE descriptionTextImageScript.urlImageOut TO urlImage.url ROUTE descriptionTextImageScript.scalePreviewImage TO ImageSpace.scale } PROTO Object [ eventIn SFFloat transparency eventIn MFNode setModel eventIn SFNode infoNode exposedField SFColor textColor .18 .0902 1 eventIn MFString text ]{ DEF modelGroup Group { children [ Shape { geometry Sphere { } appearance Appearance { material Material { diffuseColor .8 .51 .09 specularColor .92 .43 .01 ambientIntensity .117 shininess .4 transparency IS transparency } } } ] } Shape { geometry Sphere { radius 1 } appearance Appearance { material Material { transparency 1 } } } DEF textTransform Transform { scale 0.5 0.8 0.8 translation 0 1 0 children [ Shape { appearance Appearance { texture DEF FONTT ImageTexture { url "groot.gif" #repeatS FALSE repeatT FALSE } #tahoma4.gif material Material { diffuseColor IS textColor transparency IS transparency specularColor .25 .12 .78 emissiveColor .08 .04 .26 ambientIntensity .0633 shininess .07 } } geometry DEF TEXT Text { fontStyle FontStyle { # family ["TEXTURE"] family ["TEXTURE 0 255 16 16 0.8 0 0"] justify "MIDDLE" style "PLAIN" size 1 } string IS text } } ] } DEF modelScript Script { directOutput TRUE eventIn SFFloat transparency IS transparency eventIn MFNode models IS setModel eventIn SFNode infoNode IS infoNode eventIn MFString setText IS text eventOut MFNode setModelOut eventOut SFVec3f translationText url "javascript: function transparency (value) { for (i = 0; i < models.length; i ++) { models[i].transparency = value; } } function models(value) { var type = infoNode.getType(); transparency(1); if (type != 'TextItem' && type != 'Audio'&& type != 'GroupNode' && infoNode.urlPreviewImage != null) for (i = 0; i < models.length; i ++) { models[i].setImageSize = new SFVec2f(infoNode.widthPreviewImage,infoNode.heightPreviewImage); models[i].setImage = new MFString(infoNode.urlPreviewImage); } setModelOut = value; } function setText(value) { translationText = new SFVec3f(0,(value.length + 0.25) * 0.8, 0); } " } ROUTE modelScript.setModelOut TO modelGroup.children ROUTE modelScript.translationText TO textTransform.translation } PROTO ConnectionConceptGraph [ eventIn SFFloat endTransparency eventIn SFBool update eventIn SFColor setColor eventIn SFNode node1 eventIn SFNode node2 eventIn SFNode setRemoveAddScript eventIn SFNode me eventIn SFBool start eventOut SFNode node1Out eventOut SFNode node2Out ] { Shape { geometry IndexedLineSet { coord DEF Coords Coordinate { } coordIndex[0 1] } appearance Appearance { material DEF ConMattie Material { diffuseColor IS setColor specularColor .35 .14 0 ambientIntensity .143 shininess .13 } } } DEF timeS TimeSensor { loop TRUE enabled TRUE } DEF PointScript Script { directOutput TRUE eventIn SFNode removeAddScript IS setRemoveAddScript eventIn SFBool update IS update eventIn SFNode node1 IS node1 eventIn SFNode node2 IS node2 eventIn SFFloat endTransparency IS endTransparency eventIn SFTime timer eventIn SFBool start IS start eventIn SFNode me IS me eventOut MFVec3f points eventOut SFNode node1Out IS node1Out eventOut SFNode node2Out IS node2Out eventOut SFFloat transparency field SFFloat beginTransparency 1 field SFFloat totaletijd 2 field SFTime begintijd 0 field SFBool initialized FALSE field SFBool on FALSE url "javascript: function init () { initialized = true; transparency = 1; } function timer(value) { var factor; if (on) { factor = (value - begintijd) / totaletijd; if (factor < 1) { transparency = 1-Math.pow(1-(factor * (endTransparency - beginTransparency) + beginTransparency),4); } else { on = false; transparency = endTransparency; if (transparency > 0.99) removeConnection(); } } } function start(value,time) { if (!initialized) { init(); } begintijd = time; beginTransparency = 1- Math.pow(1-transparency,1/4); on = true; } function removeConnection() { removeAddScript.removeConnection = me; node1.removeConnection = me; node2.removeConnection = me; } function node1(value) { node1Out = node1; } function node2(value) { node2Out = node2; } // compute the new points on the connection, the points are moved away from the center of the nodes // to avoid overlapping of the lines and the model, which causes strange effects when models and connection are transparent function update(value) { var t1 = node1.translation; var t2 = node2.translation; var d = new SFVec3f(t1.x-t2.x,t1.y-t2.y,t1.z-t2.z); var length = Math.sqrt(d.x * d.x + d.y * d.y + d.z * d.z); factor1 = node1.scale.x * node1.scaledSize.x / length; factor2 = node2.scale.x * node2.scaledSize.x / length; points[0] = new SFVec3f(-factor1 * d.x + t1.x, -factor1 * d.y + t1.y,-factor1 * d.z + t1.z); points[1] = new SFVec3f(t2.x + factor2 * d.x,t2.y + factor2 * d.y,t2.z + factor2 * d.z); } " } ROUTE PointScript.points TO Coords.point ROUTE timeS.time TO PointScript.timer ROUTE PointScript.transparency TO ConMattie.transparency } PROTO Node [ eventIn MFNode connectedNodes eventIn SFBool getRadiusWithChildren eventIn SFBool getRadiusWithGrandChildren eventIn MFNode drawChildNodes2Deep eventIn SFNode me eventIn SFVec3f endTranslation eventIn SFFloat endTransparency eventIn SFBool start eventIn MFNode drawConnections2Deep eventIn MFNode setDrawnNodes eventIn SFNode addConnection eventIn SFNode setRemoveAddScript eventIn SFNode removeConnection eventIn SFBool clickedOnNode eventIn MFNode setModel eventIn SFNode setInfoObject eventIn SFFloat setRotation eventIn SFNode setParent eventIn SFFloat endScale eventIn SFBool deactivateClicking eventOut SFNode infoToDescription eventOut SFNode infoObject eventOut SFVec3f translation eventOut SFFloat radiusWithChildren eventOut SFFloat radiusWithGrandChildren eventOut MFNode nodesToBeDrawnList eventOut MFNode drawnNodesListToParent eventOut SFBool canBeRemoved eventOut MFNode addNewConnection eventOut SFVec3f endTranslationOut eventOut MFNode connectionToBeAddedOut eventOut MFNode connectionListToParent eventOut SFNode isSelected eventOut SFFloat radiusWithText eventOut MFString nodeText eventOut SFVec3f scaledSize field SFVec3f scale 1 1 1 field SFString ID "" exposedField SFColor diffuseColor .8 .51 .09 eventIn SFFloat setMaxRadius ]{ DEF transformAndTransparencyScript Script { directOutput TRUE eventIn SFTime time eventIn SFVec3f endTranslation IS endTranslation eventIn SFFloat endTransparency IS endTransparency eventIn SFBool start IS start eventIn MFNode connections eventIn SFFloat endScale IS endScale field SFTime beginTimeTranslation 0 field SFBool enabled FALSE field SFTime totalTime 2 field SFVec3f beginTranslation 0 0 0 field SFFloat beginTransparency 0 field SFVec3f beginScale 1 1 1 eventOut SFVec3f translation IS translation eventOut SFFloat transparency eventOut SFBool canBeRemoved IS canBeRemoved eventOut SFVec3f endTranslationOut IS endTranslationOut eventOut SFVec3f scale IS scaledSize url "javascript: function initialize () { translation = new SFVec3f(0,0,0); transparency = 1; scale = new SFVec3f(1,1,1); } function endTranslation(value) { canBeRemoved = false; if (transparency > 0.99) { translation = value; } endTranslationOut = value; } function start(value,time) { beginTimeTranslation = time; beginTranslation = translation; beginTransparency = transparency; beginScale = scale; enabled = true; } // interpolation of scale, translation and transparency of a concept graph node. // see buttonbar.wrl for explanation of interpolation function time(value) { if (enabled) { var factor = (value - beginTimeTranslation)/totalTime; if (factor < 1) { translation = new SFVec3f((1-Math.pow(1-factor,3)) * (endTranslation.x - beginTranslation.x) + beginTranslation.x, (1-Math.pow(1-factor,3)) * (endTranslation.y - beginTranslation.y) + beginTranslation.y, (1-Math.pow(1-factor,3)) * (endTranslation.z - beginTranslation.z) + beginTranslation.z); transparency = factor * (endTransparency - beginTransparency) + beginTransparency; scale = new SFVec3f(factor * (endScale - beginScale.x) + beginScale.x, factor * (endScale - beginScale.y) + beginScale.y, factor * (endScale - beginScale.z) + beginScale.z); updateConnections(); } else { factor = 1; scale = new SFVec3f(endScale, endScale, endScale ); translation = endTranslation; updateConnections(); transparency = endTransparency; enabled = false; if (endTransparency > 0.99) { canBeRemoved = true; //print('Node can be removed'); } } } } function updateConnections() { for (i = 0; i < connections.length; i ++) { connections[i].update = true; } } " } DEF timer TimeSensor { enabled TRUE loop TRUE } ROUTE timer.time TO transformAndTransparencyScript.time DEF temptrans Transform { translation IS translation children [ # Transform { # translation 0 0 -0.5 # scale 1 1 0.1 # children [ # #needed to check the radius of the node including the text visually, do not remove # Shape { # geometry Sphere { # radius 1 # } # appearance Appearance { # material Material { # diffuseColor .32 .54 .26 # specularColor .46 .46 .46 # ambientIntensity .0933 # shininess .51 # } # } # } # ] # } ] } DEF nodeTransform Transform { translation IS translation scale IS scale children [ DEF scaleTransform Transform { children [ DEF Ts_Sphere TouchSensor { } DEF nodeObject Object { textColor IS diffuseColor setModel IS setModel infoNode IS setInfoObject } ] } ] } ROUTE transformAndTransparencyScript.scale TO scaleTransform.scale ROUTE transformAndTransparencyScript.transparency TO nodeObject.transparency DEF Sphere_Script Script { directOutput TRUE eventIn MFNode connectedNodes IS connectedNodes eventIn MFNode drawChildNodes2Deep IS drawChildNodes2Deep eventIn SFBool clickedOnNode IS clickedOnNode eventIn SFBool getRadiusWithChildren IS getRadiusWithChildren eventIn SFBool getRadiusWithGrandChildren IS getRadiusWithGrandChildren eventIn SFNode me IS me eventIn SFVec3f endTranslation IS endTranslation eventIn SFNode addConnection IS addConnection eventIn MFNode drawConnections2Deep IS drawConnections2Deep eventIn MFNode setDrawnNodes IS setDrawnNodes eventIn SFNode removeAddScript IS setRemoveAddScript eventIn SFNode removeConnection IS removeConnection eventIn SFBool isOver eventIn SFNode setInfoObject IS setInfoObject eventIn SFFloat setRotation IS setRotation eventIn SFNode setParent IS setParent eventIn SFFloat setMaxRadius IS setMaxRadius eventIn SFBool deactivateClicking IS deactivateClicking eventOut SFNode infoToDescription IS infoToDescription eventOut SFFloat radiusWithText IS radiusWithText eventOut SFFloat radiusWithChildren IS radiusWithChildren eventOut SFFloat radiusWithGrandChildren IS radiusWithGrandChildren eventOut MFNode nodesToBeDrawnList IS nodesToBeDrawnList eventOut MFNode drawnNodesListToParent IS drawnNodesListToParent eventOut MFNode connectionToBeAddedOut IS connectionToBeAddedOut eventOut MFNode connections eventOut MFNode connectionListToParent IS connectionListToParent eventOut SFNode isSelected IS isSelected eventOut SFNode infoObject IS infoObject eventOut MFString nodeText field SFVec3f scale IS scale field MFNode connectionsToBeAddedList [] field SFColor colorStarLink .91 .44 .35 field SFColor inbetweenLink .3 .3 .3 #.15 .14 .71 field SFFloat letterWidth 1 field SFFloat ownRotation 0 url "javascript: function setInfoObject (value) { infoObject = value; initializeText(); } function isOver (value) { if (value) { infoToDescription = setInfoObject; } else { infoToDescription = null; } } // if clicked: exand the node function clickedOnNode(value) { if (value && !deactivateClicking){ ownRotation = 0; expand(); me.endTranslation = me.endTranslationOut; //zorgt ervoor dat canBeRemoved false wordt, kan beter op andere manier me.endTransparency = 0; me.endScale = 1; isSelected = me; //c } } // creates a MFString that contains the text from text, on each line max 'size' characters // if possible, line ends are put behind whitespaces. function fitText(text,size) { var textToNode = new MFString(); var positionSpace = 0; var beginPosition = 0; var stop = false; while (!stop) { textLine = new String(''); if (text.length - beginPosition > size) { positionSpace = beginPosition + size; for (i = beginPosition; i < size + beginPosition; i ++) { if (text.charAt(i) == ' ') { positionSpace = i; } } } else positionSpace = text.length; for (i = beginPosition; i < positionSpace; i ++) { textLine += text.charAt(i); } textToNode[textToNode.length] = textLine; beginPosition = positionSpace + 1; if (beginPosition >= text.length) stop = true; } return textToNode; } // makes the short name fit under concept graph nodes // sets the radius of the node including its text function initializeText() { var textToNode = new MFString(); var positionSpace = 0; var beginPosition = 0; var stop = false; nodeText = fitText(infoObject.shortName,16); radiusWithText = 1.7; //if ((scale.x + (Math.pow(nodeText.length,1/2) - 0.5) * scale.x * 0.8) > (scale.x * nodeText[0].length * letterWidth / 4 / 2)) // radiusWithText = (scale.x + (Math.pow(nodeText.length,1/2) - 0.5) * scale.x * 0.8); //else radiusWithText = (scale.x * nodeText[0].length * letterWidth / 4 / 2); //print(me.ID + ' radius With text is: ' + radiusWithText + 'textLength = ' + nodeText[0].length); // radiusWithText = Math.sqrt(Math.pow(scale.x + scale.x * 0.8 * nodeText.length,2) + Math.pow(scale.x * nodeText[0].length/6,2)); } function expand() { connectionsToBeAddedList = new MFNode(); nodesToBeDrawnList = drawChildNodes(); connectionToBeAddedOut = connectionsToBeAddedList; //houd deze volgorde aan! (zie removeAddscript start scene) } function drawChildNodes() { var radius; var locationChild; var drawnNodes = new MFNode(me); drawnNodes = merge(connectedNodes,drawnNodes); for (i = 0; i < connectedNodes.length; i ++) { maxRadius = computeMaxRadius(12); //12 is max radius voor middelste node connectedNodes[i].setMaxRadius = maxRadius; connectedNodes[i].getRadiusWithChildren = true; radius = connectedNodes[i].radiusWithChildren; // radius is maximaal maxRadius locationChild = computeLocation(radius, i,connectedNodes.length); connectedNodes[i].endTranslation = locationChild; connectedNodes[i].setParent = me; connectedNodes[i].setRotation = computeRotationChild(i,connectedNodes.length); connectedNodes[i].endTransparency = 0; if (maxRadius < connectedNodes[i].radiusWithText) connectedNodes[i].endScale = maxRadius / connectedNodes[i].radiusWithText; else connectedNodes[i].endScale = 1; connectionsToBeAddedList = addToToBeAddedConnections(connectionsToBeAddedList,me,connectedNodes[i],colorStarLink); } for (i = 0; i < connectedNodes.length; i ++) { connectedNodes[i].setDrawnNodes = drawnNodes; connectedNodes[i].drawConnections2Deep = connectionsToBeAddedList; connectionsToBeAddedList = connectedNodes[i].connectionListToParent; connectedNodes[i].drawChildNodes2Deep = drawnNodes; drawnNodes = connectedNodes[i].drawnNodesListToParent; } return drawnNodes; } // see concept graph documentation function computeMaxRadius(height) { var aantal; var result; if (connectedNodes.length > 2) aantal = connectedNodes.length; else aantal = 2; var sinalpha = Math.sin(3.14159 / aantal); result = height * sinalpha / (1 + sinalpha); if (height - 2 * result < radiusWithText) { result = (height - radiusWithText) / 2; } return result; } function computeRotationChild(i,N) { return computeRotation(i,N) + ownRotation; } function setRotation(value) { number = lookUpInArray(setParent,connectedNodes); ownRotation = value - 3.14 - computeRotation(number,connectedNodes.length); } function drawConnections2Deep(value) { var localVarConnections = value; if (setMaxRadius >= 3) // gelijk houden met node teken conditie for (i = 0; i < connectedNodes.length; i ++) { if (!isInArray(connectedNodes[i],setDrawnNodes)) { localVarConnections = addToToBeAddedConnections(localVarConnections,me,connectedNodes[i],colorStarLink); } else { localVarConnections = addToToBeAddedConnections(localVarConnections,me,connectedNodes[i],inbetweenLink); } } connectionListToParent = localVarConnections; } function addToToBeAddedConnections(array,node1,node2,color) { if (!connectionInArray(node1,node2,array)) { var position; position = lookForConnection(connections,node1,node2); if (position == -1) { array[array.length] = Browser.createVrmlFromString('ConnectionConceptGraph {}')[0]; array[array.length - 1].node1 = node1; array[array.length - 1].node2 = node2; array[array.length - 1].setColor = new SFColor(color.r,color.g,color.b); addConnection(array[array.length - 1]); node2.addConnection = array[array.length -1]; } else { array[array.length] = connections[position]; array[array.length - 1].setColor = new SFColor(color.r,color.g,color.b); } array[array.length - 1].endTransparency = 0; //deze regel is nodig!!! voor snel klikkers } return array; } function lookForConnection(array,node1,node2) { for (i = 0; i < array.length; i ++) { if ((array[i].node1Out.ID == node1.ID && array[i].node2Out.ID == node2.ID) || (array[i].node1Out.ID == node2.ID && array[i].node2Out.ID == node1.ID)) return i; } return -1; } function addConnection(value) { if (!connectionInArray(value.node1Out,value.node2Out,connections)) { connections[connections.length] = value; value.me = value; value.setRemoveAddScript = removeAddScript; } } function connectionInArray(node1,node2,array) { for (i = 0; i < array.length; i ++) { if ((array[i].node1Out.ID == node1.ID && array[i].node2Out.ID == node2.ID) || (array[i].node1Out.ID == node2.ID && array[i].node2Out.ID == node1.ID)) { return true; } } return false; } function drawChildNodes2Deep(value) { var radius = 0; var locationChild; var drawnNodes = value; var maxRadius = computeMaxRadius(setMaxRadius); if (setMaxRadius >= 3) //gelijk houden met connectie conditie for (i = 0; i < connectedNodes.length; i ++) { if (!isInArray(connectedNodes[i],drawnNodes)) { radius = connectedNodes[i].radiusWithText; if (maxRadius < radius) { connectedNodes[i].endScale = maxRadius / radius; radius = maxRadius; } else { connectedNodes[i].endScale = 1; } locationChild = computeLocation(radius, i,connectedNodes.length); connectedNodes[i].setParent = me; connectedNodes[i].setRotation = computeRotationChild(i,connectedNodes.length); connectedNodes[i].endTranslation = locationChild; connectedNodes[i].endTransparency = 0.5; drawnNodes = add(connectedNodes[i],drawnNodes); } } drawnNodesListToParent = drawnNodes; } function add(value,array) { array[array.length] = value; return array; } function merge(array1,resultarray) { var resultIndex = resultarray.length; var teller = 0; for (i = 0; i < array1.length; i ++) { if (!isInArray(array1[i],resultarray)) { resultarray[resultIndex + teller] = array1[i]; teller ++; } } return resultarray; } // returns true if element is in the array, else returns false function isInArray(element,array) { for (i = 0; i < array.length; i ++) { if (array[i].ID == element.ID) return true; } return false; } function lookUpInArray(element,array) { for (i = 0; i < array.length; i ++) { if (array[i].ID == element.ID) return i; } return -1; } function getRadiusWithChildren(value) { // bereken voor ieder kind de afstand tot zichzelf // neem nu het maximum // dit wordt de straal van zichzelf var tempDist = 0; var maxDist = 0; for (i = 0; i < connectedNodes.length; i ++) { tempDist = computeDistance(connectedNodes[i].radiusWithText,connectedNodes.length); tempDist += connectedNodes[i].radiusWithText;//+marge 0.01 if (tempDist > maxDist) maxDist = tempDist; } if (maxDist > setMaxRadius) maxDist = setMaxRadius; radiusWithChildren = maxDist; } // computes location of the node: it computes the distance to the current node and the rotation function computeLocation(straal,i,N) { var distance = computeDistance(straal,N); var rotation = computeRotationChild(i,N); return new SFVec3f(2 * distance * Math.sin(rotation) + endTranslation.x,distance * Math.cos(rotation) + endTranslation.y, endTranslation.z); //return new SFVec3f(distance * Math.sin(rotation) + endTranslation.x,distance * Math.cos(rotation) + endTranslation.y, endTranslation.z); } //computes the distance to the current node // the distance is computed from the availabe angle in which the node can be drawn // this angle is 6.28/N. (each node gets the same angle) // using the tangens, the distance it must be drawn from the current node is computed // there is also a minimum drawing distance to avoid collision function computeDistance(straal,N) { var distance; if (N > 1) distance = (straal)/Math.sin(6.28 / N / 2); else distance = 0; var minimumDistance = (radiusWithText + straal);// + 0.1; // minimum drawing distance is twice the sum of the radius if (distance < minimumDistance) return minimumDistance; else return distance; } function removeConnection (value) { for (i = 0; i < connections.length; i ++) { if (connectionIsEqual(connections[i],value)) { connections[i] = connections[connections.length - 1]; connections.length = connections.length - 1; //print('Connection removed'); } } } function connectionIsEqual(connection1,connection2) { return ((connection1.node1Out.ID == connection2.node1Out.ID && connection1.node2Out.ID == connection2.node2Out.ID) || (connection1.node1Out.ID == connection2.node2Out.ID && connection1.node2Out.ID == connection2.node1Out.ID)); } // the available angle is divided in 'the number of connected nodes' pieces. function computeRotation(i,N) { return 2 * 3.14159/N * i; } " } DEF tempScript Script { # test script for displaying radius with text eventIn SFFloat radius eventOut SFVec3f radiusOut url "javascript: function radius (value) { radiusOut = new SFVec3f(value,value,1); } " } ROUTE Sphere_Script.radiusWithText TO tempScript.radius ROUTE tempScript.radiusOut TO temptrans.scale ROUTE Sphere_Script.nodeText TO nodeObject.text ROUTE Sphere_Script.connections TO transformAndTransparencyScript.connections ROUTE transformAndTransparencyScript.translation TO nodeTransform.translation ROUTE transformAndTransparencyScript.translation TO temptrans.translation ROUTE Ts_Sphere.isActive TO Sphere_Script.clickedOnNode ROUTE Ts_Sphere.isOver TO Sphere_Script.isOver } PROTO ConceptGraph[ eventIn MFNode setNodes eventIn SFString show eventOut SFString clickedOnNode eventOut SFString historyAdd exposedField SFVec3f viewpointPosition 0 0 20 eventOut SFBool ready eventOut SFFloat endTransparencyCGButtons eventOut SFString nodeTitle eventOut SFBool deactivateClicking eventOut SFString exit # exit presentation environment eventOut SFString showNodePG # show presentationenvironment eventOut SFBool exitButtons # exit presentation environment buttons eventOut SFBool selectMiddleWindow # eventOut SFString text # eventOut SFBool MaxMiddleWindow # eventOut SFBool minimizeWindow # eventOut SFTime playAudio # eventOut SFBool exit3Dinstallation # ]{ Viewpoint { position IS viewpointPosition } DEF scene Transform { # groepeert de sphere group en connection group. children [ DEF sphereGroup Group { children [] } DEF connectionGroup Group { children [] } ] } DEF helpScreen helpScreen {} DEF MainModelSW Switch { whichChoice 0 choice [ Transform { translation -23.15 2.5 0 children [ DEF homeModel MainModel {} DEF homeButton TouchSensor {} ] } ] } Transform { translation -23 10 0 children [ DEF questionMark QuestionMark { } ] } DEF guidedTourModelSW Switch { whichChoice 0 choice [ Transform { translation -23 -0.8 0 children [ DEF guidedTourModel GuidedTourModel {} DEF guidedTourTS TouchSensor {} ] } ] } DEF helpButtonScript Script { eventOut SFFloat endTransparencyQuestionMark IS endTransparencyCGButtons eventIn SFString show IS show url "javascript: function show(value) { if (value != null) endTransparencyQuestionMark = 0; else endTransparencyQuestionMark = 1; } " } DEF homeModelScript Script { eventIn SFBool rollover eventIn SFTime time eventIn SFFloat setTransparency field SFFloat beginTransparency 0 field SFTime beginTimeTransparency 0 field SFBool transparencyEffectEnabled FALSE field SFFloat totalTimeTransparency 2 eventOut SFInt32 whichchoice eventOut MFString rollOverText eventOut SFFloat transparency url "javascript: function initialize() { transparency = beginTransparency; } // interpoltaion of transparency: see buttonbar.wrl for explanation function time(value) { if (transparencyEffectEnabled) { var factor = (value - beginTimeTransparency) / totalTimeTransparency; //print('factor home is: '+factor); if (factor < 1) { transparency = factor * (setTransparency - beginTransparency) + beginTransparency; } else { transparency = setTransparency; transparencyEffectEnabled = false; if (setTransparency == 1) whichchoice = -1; } } } function setTransparency (value,time) { //print('transparantie home is: '+value); whichchoice = 0; beginTimeTransparency = time; beginTransparency = transparency; transparencyEffectEnabled = true; } function rollover(value){ if (value){ rollOverText = 'home'; } else{ rollOverText = ''; } } " } DEF rollOverHomeText Transform { # rollover text for the home button translation -21.5 2.2 0 children [ Shape { geometry DEF rolloverHomeText Text { string "" } } ] } DEF guidedTourScript Script { eventIn SFBool rollover eventIn SFTime time eventIn SFFloat setTransparency field SFFloat beginTransparency 0 eventOut SFFloat transparency field SFTime beginTimeTransparency 0 field SFBool transparencyEffectEnabled FALSE field SFFloat totalTimeTransparency 2 eventOut SFInt32 whichchoice eventOut MFString rollOverText url "javascript: function initialize() { transparency = beginTransparency; } // interpoltaion of transparency: see buttonbar.wrl for explanation function time(value) { if (transparencyEffectEnabled) { var factor = (value - beginTimeTransparency) / totalTimeTransparency; if (factor < 1) { transparency = factor * (setTransparency - beginTransparency) + beginTransparency; } else { transparency = setTransparency; transparencyEffectEnabled = false; if (setTransparency == 1) whichchoice = -1; } } } function setTransparency (value,time) { whichchoice = 0; beginTimeTransparency = time; beginTransparency = transparency; transparencyEffectEnabled = true; } function rollover(value){ if (value){ rollOverText = 'guided tour'; } else{ rollOverText = ''; } } " } DEF rollOverGuidedTourText Transform { # rollover text for the home button translation -21.5 -1.2 0 children [ Shape { geometry DEF guidedTourText Text { string "" } } ] } DEF timerSceneTranslation TimeSensor { enabled TRUE loop TRUE } ROUTE timerSceneTranslation.time TO homeModelScript.time ROUTE timerSceneTranslation.time TO guidedTourScript.time ROUTE homeButton.isOver TO homeModelScript.rollover ROUTE homeModelScript.rollOverText TO rolloverHomeText.string ROUTE guidedTourTS.isOver TO guidedTourScript.rollover ROUTE guidedTourScript.rollOverText TO guidedTourText.string ROUTE questionMark.clicked TO helpScreen.help ROUTE helpButtonScript.endTransparencyQuestionMark TO questionMark.setTransparency ROUTE helpButtonScript.endTransparencyQuestionMark TO guidedTourScript.setTransparency ROUTE helpButtonScript.endTransparencyQuestionMark TO homeModelScript.setTransparency ROUTE homeModelScript.transparency TO homeModel.transparency ROUTE homeModelScript.whichchoice TO MainModelSW.whichChoice ROUTE guidedTourScript.transparency TO guidedTourModel.transparency ROUTE guidedTourScript.whichchoice TO guidedTourModelSW.whichChoice DEF SceneSetToCenter Script { #dit script zorgt ervoor dat bij veranderen van de navigatie graph, de scene waarin deze geplaatst is dmv nodes en connections, in het midden van het scherm komt te staan. Het midden is een translation van 0.0.0. eventIn SFVec3f setSceneCenter # translation van de geselecteerde node (de huidige node die geactiveerd is) -->uit het removeAddScript eventIn SFTime timer # geeft time events voor de interpolatie. field SFTime startTime 0 # begin tijd van de interpolatie (timer activatie) field SFTime totalTime 2 # totaltijd die nodig is voor de interpolatie. field SFVec3f startPosition 0 0 0 field SFBool move FALSE eventOut SFVec3f setSceneTranslation # zet de translation van de scene (naar 0.0.0.). url "javascript: function initialize (){ setSceneTranslation = new SFVec3f(0,0,0); } function timer (value){ if (move) { var factor; factor = (value - startTime) / totalTime; if (factor < 1){ setSceneTranslation.x = factor * (-setSceneCenter.x - startPosition.x) + startPosition.x; setSceneTranslation.y = factor * (-setSceneCenter.y - startPosition.y) + startPosition.y; setSceneTranslation.z = factor * (-setSceneCenter.z - startPosition.z) + startPosition.z; } else { setSceneTranslation.x= -setSceneCenter.x; setSceneTranslation.y= -setSceneCenter.y; setSceneTranslation.z= -setSceneCenter.z; move = false; } } } function setSceneCenter(value,time){ //time wordt time van event. startTime = time; startPosition = setSceneTranslation; move = true; } " } DEF removeAddScript Script { #dit script zorgt voor het verwijderen en toevoegen van de nodes en connecties in de groups (scenes) directOutput TRUE eventIn MFNode nodesToBeDrawnList eventIn MFNode connectionsToBeAdded eventIn SFNode removeConnection eventIn SFBool removeNode # removes node when it is set to transparant 1 --> canBeRemoved is then set to 'true' <-- in TT. script! Node must be removed. eventIn SFString show IS show eventIn MFNode allNodes IS setNodes eventIn SFBool homeButtonClick field MFNode nodesOnScreen [] field MFNode connectionsToScene [] field MFNode newChildren [] eventOut SFBool deactivateClicking eventOut MFNode addConnectionsToScene eventOut MFNode addChildrenToScene eventOut SFVec3f setSceneCenter # this eventout is used by the scene script to get the translation coordinates of the selected node. eventOut SFBool resetClickedOnNode url "javascript: function show(value) { // DEZE GEBRUIKEN VOOR GUIDED-TOUR if (value != null) { resetClickedOnNode = true;; deactivateClicking = false; for (i = 0; i < allNodes.length; i ++) { if (allNodes[i].ID == value) { allNodes[i].clickedOnNode = true; return; } } } else { nodesToBeDrawnList(new MFNode()); connectionsToBeAdded(new MFNode()); } } function homeButtonClick(value) { if (value) { for (i = 0; i < allNodes.length; i ++) { if (allNodes[i].ID == 'MAIN') { allNodes[i].clickedOnNode = true; return; } } } } function removeConnection(value) { for (i = 0; i < connectionsToScene.length; i ++) { if (connectionIsEqual(value,connectionsToScene[i])) { connectionsToScene[i] = connectionsToScene[connectionsToScene.length - 1]; connectionsToScene.length = connectionsToScene.length - 1; } } addConnectionsToScene = connectionsToScene; } function connectionsToBeAdded(value) { for (i = 0; i < connectionsToScene.length; i ++) { if (!isInConnectionArray(connectionsToScene[i],value)) { connectionsToScene[i].endTransparency = 1; } } addToConnectionsToScene(value); addConnectionsToScene = connectionsToScene; startScene(); } function addToConnectionsToScene(connections) { for (i = 0; i < connections.length; i ++) { if (!isInConnectionArray(connections[i],connectionsToScene)) { connectionsToScene[connectionsToScene.length] = connections[i]; } } } function isInConnectionArray(connection,array) { for (i = 0; i < array.length; i ++) { if (connectionIsEqual(connection,array[i])) return true; } return false; } function connectionIsEqual(connection1,connection2) { return ((connection1.node1Out.ID == connection2.node1Out.ID && connection1.node2Out.ID == connection2.node2Out.ID) || (connection1.node1Out.ID == connection2.node2Out.ID && connection1.node2Out.ID == connection2.node1Out.ID)); } function nodesToBeDrawnList(value) { if (value.length > 0) setSceneCenter = value[0].endTranslationOut; for (i = 0; i < newChildren.length; i ++) { if (!isInArray(newChildren[i],value)) { newChildren[i].endTransparency = 1; } } addToScene(value); addChildrenToScene = newChildren; } function addToScene(value) { for (i = 0; i < value.length; i ++) { if(!isInArray(value[i],newChildren)) { newChildren[newChildren.length] = value[i]; } } } function isInArray(element,array) { for (i = 0; i < array.length; i ++) { if (array[i].ID == element.ID) return true; } return false; } function removeNode(value){ for(i = 0; i < newChildren.length; i++) { if (newChildren[i].canBeRemoved) { newChildren[i] = newChildren[newChildren.length - 1]; newChildren.length = newChildren.length - 1; addChildrenToScene = newChildren; return; } } } function startScene() { for (i = 0; i < newChildren.length; i ++) { newChildren[i].start = true; } for (i = 0; i < connectionsToScene.length; i ++) { connectionsToScene[i].start = true; } } " } ROUTE SceneSetToCenter.setSceneTranslation TO scene.translation ROUTE timerSceneTranslation.time TO SceneSetToCenter.timer ROUTE removeAddScript.setSceneCenter TO SceneSetToCenter.setSceneCenter ROUTE removeAddScript.addChildrenToScene TO sphereGroup.children ROUTE removeAddScript.addConnectionsToScene TO connectionGroup.children ROUTE homeButton.isActive TO removeAddScript.homeButtonClick DEF ClickedOnNodeScript Script { directOutput TRUE eventIn SFNode selectedNode eventOut SFString clickedOnNode IS clickedOnNode eventOut SFString historyAdd IS historyAdd eventOut SFString nodeTitle IS nodeTitle eventOut SFBool deactivateClicking field SFNode previousNode NULL url "javascript: function selectedNode(value){ if (previousNode != null && value.ID == previousNode.ID) { nodeTitle = value.infoObject.shortName; deactivateClicking = true; clickedOnNode = value.ID; // <-- Ooh! This is what opens the presentation environment! :-) [Tim] previousNode = null; } else { historyAdd = value.ID; previousNode = value; } } " } ########################## GUIDED TOUR CODE ########################### DEF GuidedTour GuidedTour { showNodePG IS showNodePG exit IS exit exitButtons IS exitButtons selectMiddleWindow IS selectMiddleWindow text IS text MaxMiddleWindow IS MaxMiddleWindow minimizeWindow IS minimizeWindow nodeTitle IS nodeTitle exit3Dinstallation IS exit3Dinstallation } DEF guidedTourActionScript Script { eventIn SFBool startGuidedTour eventIn SFBool getAudioURLPresentationEnvironment eventOut MFString setStartText eventOut SFTime playAudio IS playAudio eventOut SFInt32 disableMouseInput url "javascript: function startGuidedTour(value){ if (value) { disableMouseInput = 0; setStartText = 'guided tour is running...'; } else { setStartText = ''; disableMouseInput = -1; } } function getAudioURLPresentationEnvironment(value,time){playAudio = time;} " } DEF GuidedTourStartText Transform { translation -4 15 0 children [ Shape { geometry DEF GTStartText Text { string "" fontStyle FontStyle {family "verdana"} } appearance Appearance { material Material { diffuseColor .61 .59 0 specularColor 1 .39 .14 emissiveColor .09 .08 0 ambientIntensity .678 shininess .1 } } } ] } DEF layerdisableMouseInput Layer3D { depth -5 size 1 1 navigationInfo NavigationInfo { type "NONE" } viewpoint Viewpoint { fieldOfView 0.96 orientation 0 1 0 0.0 position 0 0 20 } children [ Transform { translation 2 0 15 children [ DEF disableMouseInputSwitch Switch { whichChoice -1 choice [ Shape { geometry Box { size 11 10 0 } appearance Appearance { material Material { transparency 1 } } } ] } DirectionalLight { direction 0 0 -1 on TRUE intensity 0.9 } ] } ] } ########################## END GUIDED TOUR CODE ########################### DEF desciptionTextImage DescriptionTextImage {} DEF InitScript Script { directOutput TRUE eventIn MFNode setNodes IS setNodes eventOut MFNode AddFirstNode eventOut SFBool ready IS ready field SFNode removeAddScript USE removeAddScript field SFNode clickedOnNodeScript USE ClickedOnNodeScript #c field SFNode descriptionBox USE desciptionTextImage #c url "javascript: function initialize() { ready = true; } function setReferences(nodes) { for (i = 0; i < nodes.length; i ++) { nodes[i].setRemoveAddScript = removeAddScript; Browser.addRoute(nodes[i],'nodesToBeDrawnList', removeAddScript, 'nodesToBeDrawnList'); Browser.addRoute(nodes[i],'connectionToBeAddedOut',removeAddScript,'connectionsToBeAdded'); Browser.addRoute(nodes[i],'canBeRemoved',removeAddScript,'removeNode'); //c Browser.addRoute(nodes[i],'isSelected',clickedOnNodeScript,'selectedNode'); //c Browser.addRoute(nodes[i],'infoToDescription',descriptionBox,'infoObject'); Browser.addRoute(removeAddScript,'deactivateClicking',nodes[i],'deactivateClicking'); Browser.addRoute(clickedOnNodeScript,'deactivateClicking',nodes[i],'deactivateClicking'); } } function setNodes(value) { setReferences(value); drawFirstNode(value); } function drawFirstNode(nodeList) { // het toevoegen van de allereerste node nodeList[0].endTranslation = new SFVec3f(0,0,0); nodeList[0].endTransparency = 0; nodeList[0].endScale = 1; nodeList[0].start = true; AddFirstNode = new MFNode(nodeList[0]); } " } ROUTE InitScript.AddFirstNode TO removeAddScript.nodesToBeDrawnList ################################# guided tour related routes ##################### ROUTE guidedTourTS.isActive TO GuidedTour.start ROUTE GuidedTour.showNodeCG TO removeAddScript.show ROUTE GuidedTour.playAudio TO guidedTourActionScript.getAudioURLPresentationEnvironment ROUTE guidedTourActionScript.disableMouseInput TO disableMouseInputSwitch.whichChoice ROUTE GuidedTour.startInitiated TO guidedTourActionScript.startGuidedTour ROUTE guidedTourActionScript.setStartText TO GTStartText.string ######################################################################################### } ConceptGraph {}