Bobs track Builder (BTB) is a 3D racing track designer that hopes to offer a new way of creating tracks. It\nfocuses on the use of curves to create the layout from which all vertex and polygon information is\ncalculated. This should allow you, the designer, a more rapid approach to make multiple modifications to\nthe design of your track without the need to edit at a vertex/polygon level. I also hope that BTB will speed\nthe process of track design too by offering tools that are not available in generic 3d packages.\nBTB will not replace the 3d editor such as 3d Max, but will be a great first step toward creating a track.\nExporting to various formats allows the use of the track models in other 3d packages such as 3DSimED,\nTrkMaker and ZModeler.
Of course none of this would have been possible without the support of many people so Iโ€™d like to thank:\nโ€ข My Wife โ€“ for understanding that I honestly wasnโ€™t up after 2am most nights MSNโ€™ing other woman\nalthough when I told her I spent most of the evening with Bob she was a little worried.\nโ€ข To my kids for not letting me program during the weekends and becoming a total geek!\nโ€ข Family and friends for their polite nodding during dinner parties.\nโ€ข Beta Testers for not letting me do too much stupid stuff even though I dreaded rewriting the Surface\nMaterials interface for the 124th time. Special thanks to freew67 for his numerous emails and words of\nsupport. Thanks also to GTVirus for his testing, feedback and creative track design.\nโ€ข Thanks to the team at http://www.mbdevteam.com/ for their great textures and for allowing them to be\nused by BTB and its users.\nโ€ข To the makers of the original 3d Max GMT Importer script; without this body of work to study I would\nnever have been able to offer the export/import feature (now obsolete, but hey I used it for a while).\nโ€ข To the RSC and BHM community who gave great technical advice and support.\nโ€ข Thanks to ISI for such a modable game and to the modders whoโ€™s content has filled my hard drive.\nโ€ข To black f for his great work on the RBR plug-in, patience and time.\nโ€ข To Flagmo-T for the wonderful Textures he has converted and supplied.\nโ€ข AolBites for his contributions and enthusiasm towards pulling real GPS data across.\nโ€ข Kai from http://richardburnsrally.de/ - he has huge bandwidth!\nโ€ข Andrew for more textures.\nโ€ข Sorry if I missed anyone?
The BTB idea stemmed from what seemed like a relatively simple concept, but as I gained a greater\nunderstanding of what is needed to make a great track, the project grew and there are many many features I\nwant to add.\nPrior to undertaking this project, I had never created a track in any racing game. My 3d graphics\nprogramming experience was very limited; I started out doing 3d wireframe cubes on a Tandy TRS-80\nabout 20 years ago and only progressed as far as doing solid colour 3d cubes with perspective about 18\nyears ago. My day job involves writing applications and reports using VB and SQL Server for a bank on\nPCโ€™s so this project involved quite a learning curve.\nMemories โ€ฆ\nhttp://forum.rscnet.org/showpost.php?p=2610206&postcount=22\nhttp://forum.rscnet.org/showthread.php?t=224016\nTrivia: itโ€™s called BTB because Bob is my middle name and that of my uncle who is a builder.\nAs of June 2007, I estimate Iโ€™ve spent about 2,000 hours writing this app, Iโ€™ve aged about 11 years and all\nmy muscle has turned to fat and has started to multiply.
โ€ข A video card capable of Shaders 2.0.\nโ€ข Windows XP 32 bit.\nโ€ข .Net 2.0 Framework (will be downloaded from Microsoft as part of install if you donโ€™t already\nhave it).\nMy sincerest apologies to anyone that canโ€™t run this application, but for the immediate future I am focusing\non putting more features into the product than spending time trying to make it work on older or rarer\nhardware.\nIf you do have the latest hardware and BTB still doesnโ€™t run, again I am sorry for this and Iโ€™ll refund your\nmoney.
These steps need to be performed once.\n1. Uninstall any previous version of BTB.\n2. Extract the contents of the zip file, then run the Setup.exe and follow the prompts. In the process,\nif you donโ€™t already have it, .Net 2.0 will be downloaded for you from the Microsoft site.\nTo uninstall, use your Control Panel โ€ฆ Add Remove Programs.
There are 3 orthogonal (2d) views (Top, Front and Right) and one 3 dimensional view. For simplicity BTB\ndoes not allow you to switch them around but they can be resized by left-clicking and dragging the borders.
2d views can be navigated using the following controls:\nโ€ข Left-click to select. Hold Shift to multi-select.\nโ€ข Middle-click and drag to translate the view.\nโ€ข Use the middle scroll wheel to zoom in and out.\nโ€ข Right click to open popup menu.\nโ€ข Use the Numeric Keypad 2, 4, 6, 8, +, - to move in/out, left/right and to zoom.
The 3d view allows the following control.\nโ€ข Left-click to rotate around the cameraโ€™s axis.\nโ€ข Shift left-click and drag to rotate around the target.\nโ€ข Middle-click and drag to translate the view. Hold shift for finer control.\nโ€ข Use the middle scroll wheel to zoom in and out.\nโ€ข Use the right mouse button to activate the hyper-thermodynamic ventilation shafts โ€ฆ not currently\nimplemented.\nโ€ข Right click to open popup menu where you can change the drawing method.\nโ€ข Use the Numeric Keypad 2, 4, 6, 8, +, - to move in/out, left/right and to zoom.\nโ€ข Click the left button, then without lifting, click and drag the right button to translate the view โ€“\nuseful if you donโ€™t have a middle button.
At the top of the window is the toolbar that is divided into three sections.\nEditing\nโ€ข Create a Closed Track\nโ€ข Create an Open Track\nโ€ข Add a Background Image\nโ€ข Move Sunlight\nโ€ข Move Nodes and Control Points\nโ€ข Add New Nodes\nโ€ข Edit Track Details\nโ€ข Edit Materials and Textures\nโ€ข Edit Surface Details\nโ€ข Edit Width Modifiers\nโ€ข Edit Camber Modifiers\nโ€ข Edit Walls\nTrack Information\nโ€ข Length, Vertex and Polygon counts\nโ€ข Coordinates\n3d View Camera Control\nโ€ข Fly it\nโ€ข Drive it\nโ€ข Walk it
At the top of the Track hierarchy is the Venue. Consider this to be a location where there might be a\nnumber of related tracks. All information regarding a BTB project is contained within a Venue.\nBy default when you start BTB a new empty Venue has been created for you and you may skip to creating\nyour first track.\nYou can Save the Venue (and all related information) using the menu File โ€ฆ Save. BTB uses an XML\nformat to contain all the elements used to create the track(s). It is highly recommended that you save all\nyour tracks to the BTB\sProjects folder.\nLoad a Venue by using File โ€ฆ Open.
Although a Venue can contain more than one track, youโ€™ll only be able to edit one at a time. Select the\ntrack in the listbox and click the Make Active button to make it the editable one; alternatively double-click\non a track in the listbox. Turn a Trackโ€™s Visibility on and off to help when editing more complicated or\nlengthy tracks.\nA copy Track button allows the duplication of a track. Remove a track by selecting the track in the listbox,\nthen clicking the button.\nA Track is a curve made by clicking in the Top view window to create a series of Nodes. A curve is created\njoining the points together to serve as the basic track layout.\nTrack Type\nThere are two types of Tracks, Open or Closed. Be careful when planning a Track because currently you\ncannot change this property after it has been created.\nโ€ข Closed โ€“ for circuit racing this is a curve that use the one Node for the start and end.\nโ€ข Open โ€“ a circuit whose start and end Nodes are different.\nCurve Type\nA Track can use one of two types of curves. Iโ€™ll explain briefly what they are but itโ€™s best you try them for\nyourself to see what best suits. You can switch between these at any stage.\nโ€ข Cardinal โ€“ Good for exact alignment through but flow of curve requires more Nodes.\nโ€ข Bezier Spline โ€“ Uses a Node and two control points (Entry and Exit) to alter the flow of the track.\nProduces nice curves but can be a bit fiddly to get exact positions.\nSee View โ€ฆ Options to set the default Curve Type.\nPanel Spacing Type\nIn BTB terminology a panel is two polygons joined to make a square โ€“ many panels make up the tracks\nmesh. The track can space the panels using one of two methods and you can switch between these at any\nstage.\nโ€ข Linear - Evenly spaced regardless of the curve.\nโ€ข NonLinear โ€“ Follows the mathematics of the curve creating panels that are closer together as the\ncurve tightens.\nNote that this only affects the vertex placements, the textures can be spaced independently.\nSee View โ€ฆ Options to set the default Panel Spacing Type.
To create a Closed track:\n1. Click the toolbar item . When this is done for the first time, a Hint window pops up with\nsome simple instructions on how this is used.\n2. In the Top view, left-click to place the Node. If the Trackโ€™s Curve Type is a Spline, drag to\nmanoeuvrer the Exit Control Point. Due to a limitation in the current design, this will be the\nonly Node that you cannot delete so place it carefully.\n3. Left-click (and drag) to produce further Nodes. The Track will be produced with one Surface\nwhen at least two Nodes are created.\n4. Right-click, press Escape or click another toolbar item to exit the Node creation mode.
Creating an Open track is exactly like creating a Closed Track but instead initiate by clicking the\ntool.
A background image can be added to assist in mapping a real life track into BTB.\nโ€ข Click to add a background image or to relocate an existing image.\nโ€ข A file requester will ask for a filename, find your bitmap and select ok. Supported formats include\n.dds, .bmp, .dib, .hdr, .jpg, .pfm, .png, .ppm, and .tga however I recommend you stick with DDS\nfiles as they offer great flexibility and are widely accepted within the games industry.\nโ€ข Left-click and drag in the top view to insert the image.\nโ€ข Hold Control to resize using the images original scale.\nEight handles are located around each corner and edge of the image so you can move the image if required.\n
Now that BTB has a shadow and some shading routines I thought it would be nice to be able to\nmove the sun around albeit rather crudely.\nThe sun always lies on an imaginary hemisphere surround the track. Click in any of the 2d views to set its\nnew position. I donโ€™t enforce the placement of the sun so make it set in the North if you like.
Textures are the bitmaps, jpegs, and dds files that are the basic building block for all materials and typically\nyou would use a tool like Adobe Photoshop or Paint Shop Pro to create and edit them. They describe the\nbasic colour of the material, and where applicable, the bump and specular mapping applied to a surface.\nMaterials are what get applied directly to the surfaces of track and walls and may contain one or more\ntextures, as well as some other settings to determine the final visual result.\nBTB organises Materials into a hierarchical tree which you yourself can edit to your own needs. Click on a\nbranch within the tree sets the filter for what textures are shown in the icon panel to the right. Below is an\nexample of the road branch having been selected, and all materials falling under the road branch will be\ndisplayed. This allows a quick way of finding the material youโ€™re after.\nAll Materials shown in this Tree will be copies of the template Materials stored in the BTB folders. Any\nchanges you make to the Materials only apply to the current Venue; no other Venue future or past is\naffected. Even the tree structure itself is stored with the Venue.\nDouble-click on a Material icon to edit the Materials properties.\nPath Determines where in the Material Tree this Material is located.\nDescription A brief description of what this material is meant to represent.\nSpecular Colour Used by rFactor to determine the colour of the specular shine. A darker colour will\ndull the shine effect, a pure white colour will brighten the spot.\nSpecular Power Used by rFactor to determine how concentrated the specular effect is. Low values\n(1.0 โ€“ 3.0) spread the effect over a larger area. Higher values (8.0+) will produce a\nmore concentrated specular spot.\nrFactor Material This name must correspond to a setting within your trackโ€™s TDF file. If you are\nunsure about this setting, then please leave it alone as your track will fail to load if\nincorrectly set.\nTexture Mapping\nAs pictured above, you can load different textures to represent the Diffuse, Bump and Specular mappings.\nDiffuse determines the primary colour used to on the surface.\nBump (rFactor Only) can be used to give the impression of a more detailed surface.\nSpecular (rFactor Only) gives the ability to adjust the colour and strength of the specular effect.\nAll Materials have scale and offset amounts to allow interesting effect. Dual lane roads are easy to add by\nchanging the X scale to 2.0. Good application of scale / offsets to the bump and specular maps can reduce\nthe tiling effects.\nRotation can be performed, and is indeed necessary on walls, in order to map a texture properly. This can\nalso be used to further reduce bump / specular repetitions over the surface.\nTwo buttons also allow the textures to be flipped horizontally or vertically as required.\nThe Bump and Specular Textures can be cleared so that the surfaces using them are not so demanding upon\nsystem performance. This will be important especially for future updates where the terrain can be modelled.\nUsing Diff/Bump/Spec maps on large areas will cause degrading frame rates.\nNote that although surfaces may be specified as Diff/Bump/Spec maps, rFactor will automatically scale\nback the shaders used for DX7 and DX8 use so some of the effects will be lost. This is necessary since\nolder cards cannot support the more complicated maths required.\nRight-click an existing Material and select Clone from the menu to make a copy of that Material. Be sure to\nset a new Path property to determine where in the Material Tree it will sit and what name it will be given.\nYou can then alter the settings as required.\nRemoving a Material is not yet implemented due to time constraints. This currently has no impact on the\nfinal result as only used Materials are exported.\nFor Richard Burns Rally the front end does not yet allow you to edit the surface properties; instead this has\nto be done by editing the *.rbr files that exist for each Texture. You will find them in the Textures subfolders.
After youโ€™ve created a Track, right-click to switch to Move Node mode. Alternatively click the\nicon shown to the left. The mode will switch to allow movement of the Nodes. You can manually\nselect this mode using the toolbar.\nThere are several ways to move nodes about, all determined by which tab is activated on the\nTransformation window pictured below.
The features for this mode are still in development so currently thereโ€™s not much to see in the Edit window\nโ€“ stay tuned!\nSelecting Nodes\nYou can select Nodes by left-clicking on them individually. They, and their control points, will change\ncolour to indicate selection.\nLeft-click-drag to select surrounded Nodes.\nHold down shift to multi-select. This can also be a great way to avoid clicking on a control point which is\nnear a desired Node.\nMoving Nodes\nLeft-click and drag a Node to move it. Hold Shift if multiple Nodes are selected, otherwise just the one\nNode will be moved.\nCool feature: Hold down M to snap the current node to an existing node from any track. This can help\nmake a new pit lane by snapping the ends of an open track to other nodes of an existing closed-circuit track.\nIf working with Splines, the Control Points can also be left-clicked and dragged around.
Resizing occurs as you right-click and drag the mouse toward/away from the axis as pictured\nleft. You can position the axis by double-clicking in any of the views.\nAffect Tracks Determines which of the tracks is affected by the resize.\nAffect Background Image Does the resizing also change the background image (if one is present).\nAffect nodes When resizing only the Active Track, this option makes it possible to\nonly affect the selected nodes.\nResize exactly Enter a particular length for the Active Track and it will be resized\naccordingly. Other Tracks will be resized too depending upon the\nAffect Tracks setting.
Rotating occurs much the way resizing does, the only addition is the exact rotate textbox and buttons which\nare self explanatory.
There are two methods to create new Nodes.\nClick and Drag\nSelect the Drag-Edit mode from the toolbar, click anywhere on a curve and drag the newly created\nNode to a new location.\nKnown issue: The split always occurs at the centre of the curve and the Node moves immediately to where\nthe cursor is. The means the Control Points may not match up nicely to the place where you clicked. Itโ€™s\nstill on my list of things to improve.\nSplitting a Curve\nYou can split a selected curve into smaller fragments by using the popup menu. A curve is considered\nselected when the Nodes either side are selected.\nRight-click to open the popup menu and select one of the Split Selected options.\nThe options are:\nโ€ข Split into Half.\nโ€ข Split into Thirds.\nโ€ข Split into โ€ฆ โ€“ opens a dialog box to allow enter of how many pieces you want to divide the curve\ninto.\nThe curve will be divided into equal amounts and, if using Splines, the Control Pointโ€™s set as best as I could\nto still maintain the same curve.
The most powerful and complex section you will need to deal with is the Surface Editor.\nEvery Track consists of at least one surface but you can split it into as many surfaces as you like. You will\nneed to add a new Surface whenever you want to change the shape, the material or the panel length.
In the top left are three buttons for moving, adding and removing surface modifiers.\nYou can only move the start location of a track surface (the end is defined by the start of the next surface)\nand you cannot move the first surface as it always begins on the first node. To move a surface start, click\nthe icon, then click-drag that starting point. You can only move it somewhere between the surfaces\neither side of it. You can alternative click the left-right arrows located in the top right to switch between the\nsurfaces.\nTo add a surface, click the icon, then click anywhere on the track. The surface will be added and will\ninitially not change the cross-section shape or the materials used, that needs to be specified manually.\nTo remove a surface, select it from the listbox, then click the icon.
Name Each surface is automatically given a name which will update as you insert or\nremove other surfaces. Alternatively you can give them your own names which\nmay help when trying to identify sections of a long track.\nPanel Length (m) How far along the track, on average, will each panel extend. I use the term\npanel to describe two triangles joined together to form a rectangle(ish) shape.\nLower numbers will generate a smoother track but results in a higher polygon\ncount. A higher number will stretch the panels out further thus reducing the\npolygon count at the expensive of a blockier looking track. BTB allows you to\ntry various values quite easily without having to rebuild the entire track โ€“ thus\nyou can test in-game to judge framerates in order to achieve a good balance.\nThe actual distance used is determined by the length of the surface section, the\ncurve of the track and the position across the track.
Cross-Sections allow uneven placement of the vertices to make interesting features such as bumps, ruts and\ngutters, curbs, and partially cambered roads. You could potentially do walls with it, however itโ€™s probably\nnot the best way since they donโ€™t really need the same level of detail as a road; besides, I have other plans\nfor effective implementation of walls in BTB.\nWhen the Shape checkbox is ticked, the individual vertices can be altered as you wish to form the surface\nof the track AT THE START OF A SURFACE. I want to emphasize this as Shapes will be interpolated\nbetween surface starts. To produce a quick dip in the road you would require 3 surfaces close to each other,\neach setting the Shape with the outside two being flat and the inside one dipping.\nHereโ€™s an example, exaggerated to show the effect. Surface 2 & 4 are relatively flat and lay either side of\nSurface 3 which is raised to create a large bump.\nUse these tools to move, add and remove vertices; the co-ordinates in meters\nare also shown so you can control the position down to the centimetre.\nMoving the outside vertices left/right affects the width of the track and be careful not to overlap vertices as\nstrange results will occur. One advantage of this is when trying to fix overlapping polygons. By selecting\nall vertices (hold down shift to multi-select) and moving them to one side; a problem corner is no more.\nAdding vertices to the middle of the track adds more detail to the track surface and should allow some\ninteresting designs. Adding vertices to the edge of the track expands the width but please be aware, the\npolygons will not be displayed until they have been assigned a Surface Material.
No track mesh would any good without some materials mapped to it. This part of the surface allows you to\nclick on the cross section to select the piece of track, then click a material to change the image applied.\nSet Material checkbox Determines if this surface will alter the material properties or if they simply\ncontinue on from the previous surface. Leave this unchecked if only the shape\nof the track is to change.\nThe cross-section shows the track profile and a line will join the dots where a material already exists. Click\non any part of the line to select a Surface Material. The and icons allow materials to be added and\nremoved. When a material is added it will automatically fill the first available unmapped space. Before\nadding a new material to the surface it is best to make room by clicking and dragging the edge of an\nexisting material from one point to another.\nIf no unmapped space is available, the new Surface Material will overlap the last segment and a think line\nwill be displayed in the cross-section to indicate that more than one material has been applied to that part of\nthe track.\nYou can add the same material to the Shape more than once but be careful not to overlap the materials as\nthat will result in unexpected results.\nThe start and End positions of the material are shown by the larger red nodes shown in the cross section\ndisplay; left-click and drag a red node to another node to change what part of the track it covers.\nThe Material applied to a Surface can be selected by double-clicking the associated icon. All Materials\navailable to BTB are located in the Template Materials tab. Materials already in use by the Venue are\nlocated on the Venue Materials tab.\nDouble-clicking a Template Material icon copies it to your Venue Materials and maps the material to the\nselected surface. If you already had this Material (as defined by itโ€™s full tree path) the Template Material\nvalues will overwrite any values that were in the Venue Material.\nOn both tabs you can click on the Material Tree branches to filter what materials are displayed.\nThese buttons allow you to rotate or flip the textures. Handy for when you have a\nroad-to-grass transition that you need to use on both sides of a road. You may already have seen these\ncontrols in the Materials window; these differ by allowing two Surface Materials using the same base\nMaterial to be rotated differently.\nAdvanced Settings\nPer Panel or Per Meter Determines if the texture is mapped once on each cross section panel or should\nit be per calculated meter? The per panel option will place exactly one texture\nover a panel, the per meter option maps the texture to the underlying polygons\nbased on how far they stretch. I think most people will opt for the per meter\noption.\nAdditionally for the Per Meter option there is a meter amount and a Fit Neatly\ncheckbox. The Meter amount determines how far the texture should be\nstretched. The Fit Neatly checkbox makes the texture fit perfectly to the\navailable space by working out how much it needs to squish the texture in\norder for it to fit into the mesh without there being a fractional amount left\nover.\nThe Scale and Offsets amounts that can be used in addition to the base Materialโ€™s settings to allow\ninteresting affects.
Whilst Surfaces may have different widths there may be a need to make some width changes\nwithout wanting to modify the Surface Shape. Thatโ€™s where Width Modifiers will be useful.\nBy default a Width Modifier is added at the start of a track and it can never be moved or removed.\nClick the icon, then click on the track to add a new Width Modifier.\nClick and, then left-click and drag the Width Modifier to a new position. Unlike the Surfaces, they can\nbe reordered as you wish.\nSelect a width from the listbox, then click the icon to remove a Width Modifier.
Camber could be added using a Surfaceโ€™s Cross-Section properties, but sometimes you will want\nto add a broader general camber to the whole cross-section which is easier done using Camber\nModifier than by editing each individual vertice.\nWhen a Track is first created, one flat camber is added at the very beginning and it cannot move. Adding\nmore Camber Modifiers will cause the track to be recalculated using a linear progression between one\nCamber setting and the next.\nOn an Open Track the section of mesh after the last Camber will remain at that angle till the end. In this\ncase it might be wise to always set one Camber at the very end.
Walls are easily generated using the Wall tool. The interface is very similar to the track surface\nsince their properties are alike so I will skip over features that are the same and mention only what\nis different.\nWhen adding a wall you use the same button however, you click the start point on the track and then\ndrag to where you wish the wall to end.\nBe creative with walls. You can use them to make tunnels, roofs or even an additional road.\nFor performance reasons (both within BTB and in the games) it is better to add a number of smaller walls\nrather than one long wall.\nTip: Whilst editing, use the options to hide the walls if not needed. This will increase the rendering speeds.
Providing just a little information is the Track information panel. It shows the active trackโ€™s total Length,\nNumber of vertices used and number of polygons.\nAlso shown here is the co-ordinates that update as the cursor moves over the 2d views.
These buttons allow you to view the track in various ways.
Thanks to black f and his hard work I am now able to offer export directly to Richard Burns Rally.\nSome preparation is required before export begins:\nโ€ข Copy the following folders from BTB into your Richard Burns Rally folder, and overwrite if\nprompted.\no BTB\sSupport\sRBR\sPlugins\no BTB\sSupport\sRBR\sRX_CONTENT\nTo export to RBR:\n1. From BTB, select File โ€ฆ Export โ€ฆ then select the Richard burns Rally tab.\n2. If running for the first time, locate your Richard Burns Rally folder.\n3. Click Export. WARNING: this will clear out and overwrite any contents within the\n[YourRBRFolder]\sRX_CONTENT\sTRACK_1 folder.
Thanks to ISI this process is now a lot simpler than it used to be. BTB will directly create all you need to\nget a track running, although thereโ€™ll still be plenty of fine tuning to take care of.\nTo export to rFactor:\n1. From BTB, select File โ€ฆ Export โ€ฆ then select the rFactor tab.\n2. Confirm the rFactor Folder points to your rFactor installation.\n3. Enter in your Venue name and your Track name. These will be combined to form the path to your\ntrack files.\n4. Leave the checkboxes ticked unless you wish to override the default options.\n5. Click the Export button.\nYour track will now show up in rFactor. You will need to restart rFactor if this is the first time, however\nsubsequent loads will simply require you to exit and reload the track instead of the entire game.\nBeware though; youโ€™ve still got work to do creating AIW files. See\nhttp://forum.rscnet.org/showthread.php?t=254112 for AIW help.\nIf you intend on renaming the files or folders in rFactor these are the most important settings\nโ€ข I suggest that the AIW, CAM, GDB, SCN and TDF files should be named after the sub-folder in\nwhich they reside. See the Lienz track for a good example.\nโ€ข In the *.SCN file update the SearchPath.\nโ€ข In the *.GDB file update ALL references to your track name.\nTo load an rFactor track into Max for further editing, use the GMT Importer tool\n(http://forum.rscnet.org/showthread.php?t=235109 ). You will need to download and install the ISI โ€œPublic\ndevelopment tools V2โ€ available from http://www.rfactor.net/index.php?page=devcorner .
This format is used by some games developers or is also useful if converting to other formats.\nSelect a folder to export to and click Export. Multiple files will be created for each material used within the\ntrack. Existing *.x files may be overwritten in this folder so use with care.
If you are working with a set of your own textures on many projects, instead of having to replace the\nstandard ones each time for each Venue, it is possible to instead add your own set of default\nMaterials/Textures.\nTo do this requires a little understanding of how BTB loads default Materials when the application first\nstarts.\nYou probably know by now that Materials are applied to the surfaces and that a Material can refer to more\nthan one texture; one for the Diffuse texture and optionally another two for the Bump and Specular\nmapping.\nMany Materials can refer to the same texture making it possible to reuse Bump and Specular materials thus\nreducing the amount of texture space required by graphics cards running the tracks you build.
When BTB first opens it looks into the Materials subfolder and searches this and any subfolders for *.XML\nfiles. When it does find an XML file it looks at the contents and adds an entry to the list of available\nMaterials. At this point it does not load any Textures, merely the paths to them.\nThe resulting Materials Tree structure is built by combining the subfolder structure with the Material Name\n(as found inside the XML file). You can place your own Material.XML wherever you like; create your own\nfolders to determine your own Material Tree.\nFor each of the Material.XML files there is a corresponding jpg file (64x64 pixels) that is used as the icon\nto display what the Material represents. You must create one of these for any Material you create.
Below is the layout of the BobsTrackBuilder\sMaterials\sground\sgrass\sgrass001.xml file. The following are\ndefinitions for various parts of the file.\n\n02 Contains the name of the Material. This is added to the path of the xml file to arrive obtain the full Material Tree branch. Be careful not to put duplicate values in the same folder.\n03 A description of the Material\n04 The default value to use if this material is applied as per/meter rather than per panel.\n05 Specular power.\n06 The Red, Green and Blue components of the Specular colour.\n07 Name to match entry in the TDF file.\n08 Start of Diffuse Mapping section.\n09 Path to the Diffuse Texture. If PathType is relative then the Texture is locate under theBobsTrackBuilder folder. If PathType is absolute then the Path must be entered in full.\n10 Start of the Texture Coordinate, determines how texture is applied to a surface.\n11 Has the mapping been flipped horizontally. 1 = No, -1 = Yes.\n12 Has the mapping been flipped vertically. 1 = No, -1 = Yes.\n13 Angle of mapping rotation in degrees.\n14 Scale of the mapping. A value of 1 means it directly maps to the area. A value of 2 means the texture is applied twice in that axis.\n15 Offset determines where the texture mapping begins.\n19-28 Bump mapping setting. This entire section is optional.\n30-39 Specular mapping setting. This entire section is optional.\n\n=====================================================================================\n\n01<material>\n02<Name>grass001</Name>\n03<Description>Lush green grass</Description>\n04<PerMeterCoverage>12</PerMeterCoverage>\n05<SpecularPower>2</SpecularPower>\n06<SpecularColor R="120" G="150" B="130" />\n07<rFactorMaterialName>grass001</rFactorMaterialName>\n08<DiffMap>\n09<Path PathType="Relative">Textures\sground\sgrass\sgrass001\sground_grass001.dds</Path>\n10<texture_coordinate>\n11<FlippedHorizontal>1</FlippedHorizontal>\n12<FlippedVertical>1</FlippedVertical>\n13<Angle>0.0</Angle>\n14<scale x="1" y="1" />\n15<offset x="0" y="0" />\n16</texture_coordinate>\n17</DiffMap>\n18\n19<BumpMap>\n20<Path PathType="Relative">Textures\sground\sgrass\sgrass001\sground_grass001_b.dds</Path>\n21<texture_coordinate>\n22<FlippedHorizontal>1</FlippedHorizontal>\n23<FlippedVertical>1</FlippedVertical>\n24<Angle>0.0</Angle>\n25<scale x="1" y="1" />\n26<offset x="0" y="0" />\n27</texture_coordinate>\n28</BumpMap>\n29\n30<SpecMap>\n31<Path PathType="Relative">Textures\sground\sgrass\sgeneral\sspec\sground_grass_spec01.dds</Path>\n32<texture_coordinate>\n33<FlippedHorizontal>1</FlippedHorizontal>\n34<FlippedVertical>1</FlippedVertical>\n35<Angle>0.0</Angle>\n36<scale x="4.52" y="6.78" />\n37<offset x="0.13" y="0.65" />\n38</texture_coordinate>\n39</SpecMap>\n40</material>\n\n\n\n
โ€ข When holding Shift down to select multiple node or for dragging a bounding box, if the mouse\nleaves the boundaries of the window before you release the Shift key, then BTB still thinks that\nthe Shift is being held and subsequent edits will work in the Shifted mode. To fix this, simply\npress and release the Shift key whilst the mouse is over the edit window.\nโ€ข The Material Icons actually have tooltips which are their descriptions. Unfortunately due to a bug\nin .Net they appear behind the window instead of in front. Please call Bill and complain.\nโ€ข RBR plugin wonโ€™t allow replay or weather.
โ€ข A trackโ€™s first Node can never be deleted. I hope to address this sometime in the future.\nโ€ข Upside down tracks will have unexpected behaviour. Whilst I am aware of how to change the math to\nallow such things, it will have to wait for a future version.\nโ€ข The shadow is only a simple black copy of your track mapped to a zero height. If you place your track\nbelow zero, it will look strange.\nโ€ข If you make a spline cross over itself (i.e. One spline between two nodes that loops over itself because\nthe control points cross over) then the function used to calculate a mouse-click on the track may not\nwork accurately. I have a fix for this however it is mathematically slower so Iโ€™ve not yet implemented\nit. If you find this to be a problem, please let me know.\nโ€ข Mapping can use combinations of Diffuse/Bump/Specular maps, however the 3d windows does not\nshow the final result. You will need to export to rFactor in order to see actual effect.
<!--{{{-->\n<div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></div>\n<div class='title' macro='view title'></div>\n<div class='editor' macro='edit title'></div>\n<div class='editor' macro='edit text'></div>\n<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser'></span></div>\n<!--}}}-->
<<tiddler MainMenu>>\n\nAuthorMainMenu\nMainMenu\nDefaultTiddlers\nPluginManager\nPresentationIndex\n
<!--{{{-->\n<div id='header' class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>\n<div class='headerShadow'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n<div class='headerForeground'>\n<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n</div>\n</div>\n<div id='mainMenu' refresh='content' tiddler='AuthorMainMenu'></div>\n<div id='sidebar'>\n<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>\n<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>\n</div>\n<div id='displayArea'>\n<div id='messageArea'></div>\n<div id='tiddlerDisplay'></div>\n</div>\n<!--}}}-->
/***\nPlace your custom CSS here\n***/\n/*{{{*/\n\n\n[[StyleSheetCommon]]\n/*}}}*/\n
<!--{{{-->\n<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler permalink references jump'></div>\n<div class='title' macro='view title'></div>\n<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date [[DD MMM YYYY]]'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date [[DD MMM YYYY]]'></span>)</div>\n<div class='tagging' macro='tagging'></div>\n<div class='tagged' macro='tags'></div>\n<div class='viewer' macro='view text wikified'></div>\n<div class='viewer topbutton' macro='top'></div>\n<br><br>\n<div class='viewer' macro='navigation tiddlers:{{store.getTiddlerText("PresentationIndex").readBracketedList()}}}'></div>\n<div class='tagClear'></div>\n<!--}}}-->
"select node and not the control points" hold down shift, even if not multi-selecting and it'll never grab them. \n
[[1-Introduction]]\n[[2-Requirements]]\n[[3-Installation]]\n\n[[Navigating BTB]]\n[[3.1-Views]]\n[[3.1.1-2d Views]]\n[[3.1.2-3d View]]\n[[3.2 Toolbar]]\n\n[[4-BTB Objects]]\n[[4.1-The Venue]]\n[[4.2-The Track]]\n[[4.2.1-Create a Closed Track]]\n[[4.2.2-Create an Open Track]]\n[[4.2.3-Adding/Edit a Background]]\n[[4.2.4-Moving the Sun]]\n[[4.2.5-Modifying Materials and Textures]]\n[[4.2.6-Moving the Track]]\n[[4.2.6.1 Edit Mode]]\n[[4.2.6.2 Resize Mode]]\n[[4.2.6.3 Rotate Mode]]\n[[4.2.7-Adding Nodes]]\n[[4.3-Surface Modifiers]]\n[[4.3.1-Moving, Adding and Removing Surfaces]]\n[[4.3.2-Surface Properties]]\n[[4.3.3-Shape - Cross-Sections]]\n[[4.3.4-Surface Materials]]\n[[4.4-Width Modifiers]]\n[[4.5-Camber Modifiers]]\n[[4.6-Walls]]\n[[4.7-Track Information]]\n[[4.8-Fly It / Drive It / Walk It]]\n\n[[5-Exporting to Richard Burns Rally]]\n\n[[6-Exporting to rFactor]]\n\n[[7-Export to DirectX]]\n\n[[8-Adding your own default Materials and Textures]]\n[[8.1-Loading Default Materials]]\n[[8.2-Analysis of a Material.XML file]]\n\n[[9-Known Bugs & Limitations]]\n[[9.1-Bugs]]\n[[9.2-Limitations]]\n\n[[10-Thanks]]\n\n[[11-Background]]
Story.prototype.refreshTiddler_activelink = Story.prototype.refreshTiddler;\nStory.prototype.refreshTiddler = function (title,template,force)\n{\n var theTiddler = Story.prototype.refreshTiddler_activelink.apply(this,arguments);\n if (!theTiddler)\n return theTiddler\n var menu = document.getElementById("mainMenu");\n var links = menu.getElementsByTagName("a");\n for (var i=0; i<links.length; i++)\n {\n if (!links[i].getAttribute("tiddlyLink"))\n return;\n if (document.getElementById(this.idPrefix+(links[i].getAttribute("tiddlylink"))))\n addClass(links[i],"bold");\n else\n removeClass(links[i],"bold");\n }\n return theTiddler;\n}
config.options.chkAnimate = false;\nconfig.options.chkSinglePageMode = true;\nconfig.options.chkTopOfPageMode = false;
GettingStarted
\nSee it in action here: http://lewcid.googlepages.com/tots.html\n\n!!Editing this TW:\nOpen the TW with #author:true at the end of the url/file location to enable editing.\nPreview edits by using the "Presentation Mode" button in the MainMenu\n//(To make future editing easier, bookmark the file with #author:true at the end of the file name. One click and edit!)//\n\n!!Changing the content and order of the presentation:\nEdit the PresentationIndex tiddler to change the contents and order of the presentation.\n\n!! Customizing the default (viewing) interface.\nEdit the following tiddlers as needed:\n*PageTemplate\n*StyleSheet\n*ViewTemplate\n*EditTemplate\n*MainMenu\n\n!!Customizing the editing (author's) interface.\nEdit the following tiddlers as needed: //(Note that these files are optional, if any of them dont exist, the standard viewing one will be used instead. So if you only want to change the PageTemplate, you only need an AuthorPageTemplate tiddler.)//\n*AuthorPageTemplate\n*AuthorStyleSheet\n*AuthorViewTemplate\n*AuthorEditTemplate\n*AuthorMainMenu\n\n!!Using a different stylesheet or theme:\nUsing your own favorite stylesheet or theme is as simple as importing those tiddlers into this file.\nIf you are changing the presentation interface, just import the PageTemplate and StyleSheet. If you want to change the editing interface, you will need to copy over the PageTemplate and StyleSheet as AuthorPageTemplate and AuthorStyleSheet respectively.\n\n!!Other tips:\n* Use the tiddler StyleSheetCommon and include it using {{{[[StyleSheetCommon]]}}} in your StyleSheet and AuthorStyleSheet when making stlyesheet changes that you want applied to both the presentation and editing interface, to avoid having to type it out twice!\n*To provide easy control over the font-size, use the FontSizePlugin: http://lewcid.googlepages.com/lewcid.html#FontSizePlugin\n* If this presentation is going to be placed online, you might want to have a splash screen that displays while the TW is loading: http://lewcid.googlepages.com/lewcid.html#SplashScreenPlugin
!Dummy Tiddler 3\n\ndummy tiddler three
!Dummy Tiddler1\n\nThis is the first tiddler of your dummy presentation\n\nEdit the PresentationIndex tiddler to change the contents and order of the presentation.\n
!DummyTiddler2\n\nThis is the second tiddler of your dummy presentation
function setFooter() {\n if (document.getElementById && document.getElementById("contentFooter") ) {\n var windowHeight=findWindowHeight();\n if (windowHeight>0) {\n var contentHeight= document.getElementById('mainMenu').offsetHeight + document.getElementById("header").offsetHeight + document.getElementById("contentFooter").offsetHeight;\n var menu= document.getElementById('mainMenu');\n //var footerHeight=footerElement.offsetHeight;\n if (windowHeight-(contentHeight)>=0) {\n menu.style.position='relative';\n menu.style.marginBottom=(windowHeight-(contentHeight))+'px';\n }\n else {\n menu.style.position='';\n menu.style.marginBottom='';\n }\n }\n }\n}\nwindow.onresize = function() {\n setFooter();\n}\n\nStory.prototype.refreshTiddler_footerhack=Story.prototype.refreshTiddler;\nStory.prototype.refreshTiddler = function (title,template,force)\n{ \nvar theTiddler = Story.prototype.refreshTiddler_footerhack.apply(this,arguments);\nsetFooter();\n return theTiddler;}
http://www.rally-america.com/\n\nhttp://www.acropolisrally.gr/\n\nhttp://www.ypresrally.com/
Topofusion can be used to draw and spline a track[http://www.topofusion.com/spline.php], then use the climbing anaylisis tool [http://www.topofusion.com/climb.php]to add elevation from your local dem files to the track ... [someday bobs will be able to read Track files directly .. till then..]\n\nexport this saved, elevated track file as .csv and do the following:\n\nif you use a program such as topofusion to export your gps data as .csv you want to make sure in the program preferences you have the units set to metric - this setting affects the export function as well\nCode:\n\nZone,Easting,Northing,Elevation,Time,Elapsed Time (seconds)\n19T,332269.88,4882252.96,303.5,Wed Dec 31 19:00:00 1969,0\n19T,332298.80,4882286.70,307.9,Wed Dec 31 19:00:00 1969,0\n19T,332385.54,4882361.40,313.7,Wed Dec 31 19:00:00 1969,0\n\n\ngo to your fav spreadsheet program and get rid of Zone, Time, Elapsed time\nnow whats left, is X and Y values and your elevation in whatever units the program prefs are set to - you want meters, so metric [the X,Y location measured from whatever Datum you Have set at]\n\nwhat you need to do to get this usably into BTB ...\n\n1, get your data closer to the origin - subtract the first row from the rest of the data cause otherwise it wont be visible on screen in BTB - don't worry if you have a few negative #'s these are absolute values [if using a group of tracks, subtract the same value from all of the files you want to be relative to each other\n\n2. save to .csv\n\n3. import to BTB\n
http://www.openoffice.org/\n\nfree:\nhttp://www.gmap-pedometer.com/ - Draw .GPX files on google maps \n\n.kml to .gpx converter [free]\n\nhttp://bbs.keyhole.com/ubb/showthreaded.php/Cat/0/Number/101188/page/0 \n\nGMapToGPX\nConvert Google Maps Data Directly to GPX http://www.elsewhere.org/journal/gmaptogpx\n\nhttp://www.gpsvisualizer.com/\n\n
Get BTB - http://www.bobstrackbuilder.net/news.aspx\n\n
//{{{\nconfig.macros.def ={};\nconfig.macros.def.handler = function(place,macroName,params,wikifier,paramString,tiddler)\n{\n var sliceName = params[1]? params[1].toLowerCase() : params[0].toLowerCase();\n var def = store.getTiddlerSlice("InfoDefinitions",sliceName);\n if (def == undefined)\n {\n wikify(params[0],place);\n return false;\n }\n var theClass = params[2]? params[2] : "info";\n var container = createTiddlyElement(place,"span",null,theClass);\n wikify(params[0],container);\n if (document.all)\n {\n container.onmouseover = function(){addClass(this,"infoover");};\n container.onmouseout = function(){removeClass(this,"infoover");};\n }\n var tooltip = createTiddlyElement(container,"span",null,null);\n wikify(def, tooltip);\n\n}\n\nconfig.macros.note ={};\nconfig.macros.note.handler = function(place,macroName,params,wikifier,paramString,tiddler)\n{\n var sliceName = params[1]? params[1].toLowerCase() : params[0].toLowerCase();\n var def = store.getTiddlerSlice("InfoDefinitions",sliceName);\n if (def == undefined)\n {\n wikify(params[0],place);\n return false;\n }\n var theClass = params[2]? params[2] : "note";\n var container = createTiddlyElement(place,"span",null,theClass);\n wikify("^^"+params[0]+"^^",container);\n if (document.all)\n {\n container.onmouseover = function(){addClass(this,"noteover");};\n container.onmouseout = function(){removeClass(this,"noteover");};\n }\n var tooltip = createTiddlyElement(container,"span",null,null);\n wikify(def, tooltip);\n\n}\n\n//}}}\n
/***\n|''Name:''|LegacyStrikeThroughPlugin|\n|''Description:''|Support for legacy (pre 2.1) strike through formatting|\n|''Version:''|1.0.1|\n|''Date:''|Jul 21, 2006|\n|''Source:''|http://www.tiddlywiki.com/#LegacyStrikeThroughPlugin|\n|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|\n|''License:''|[[BSD open source license]]|\n|''CoreVersion:''|2.1.0|\n|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|\n\n***/\n\n//{{{\n\n// Ensure that the LegacyStrikeThrough Plugin is only installed once.\nif(!version.extensions.LegacyStrikeThroughPlugin)\n {\n version.extensions.LegacyStrikeThroughPlugin = true;\n\nconfig.formatters.push(\n{\n name: "legacyStrikeByChar",\n match: "==",\n termRegExp: /(==)/mg,\n element: "strike",\n handler: config.formatterHelpers.createElementAndWikify\n});\n\n} // end of "install only once"\n//}}}\n
- [[Bobโ€™sTrackBuilderUserManual]]\n- BTBKeyboardShortcuts\n- GPSImport\n- ToolsToUse\n- TerrainTools\n- GPSDataSources\n- GPSdataTools\n- SegmentTracks\n- ReverseTracks
The design will be vaguely familiar to anyone that has used a 3d modeling application.
// Resolves a Tiddler reference or tiddler title into a tiddler title string, or null if it doesn't exist\nresolveTitle = function(t)\n{\n if (t instanceof Tiddler) t = t.title;\n return store.tiddlerExists(t) ? t : null;\n}\n\nconfig.macros.navigation = {};\nconfig.macros.navigation.handler = function(place,macroName,params,wikifier,paramString,tiddler)\n{\n\n if (!store.tiddlerExists(tiddler.title))\n return false;\n var e = createTiddlyElement(place,"span",null,"nav");\n e.setAttribute("refresh","macro");\n e.setAttribute("macroName",macroName);\n e.setAttribute("params",paramString);\n e.setAttribute("tiddler",tiddler.title)\n this.refresh(e,paramString);\n}\n\nconfig.macros.navigation.refresh = function(place,params)\n{\n var tiddler = store.getTiddler(place.getAttribute("tiddler"));\n removeChildren(place);\n\n\n var params = place.getAttribute("params").parseParams("tiddlers",null,true);\n//alert(store.getTiddlerText(getParam(params,"index",undefined)).parseParams("tiddlers",null,false))\n var tiddlers = getParam(params,"tiddlers",undefined);\nif (typeof tiddlers == 'string')\n tiddlers = tiddlers.readBracketedList();\n if (tiddlers == undefined)\n alert("no source tiddlers defined for navigation");\n var contents = [];\n for (var i=0;i<tiddlers.length;i++)\n {\n var title = resolveTitle(tiddlers[i]);\n contents.push(title);\n}\n var navIndex = contents.indexOf(tiddler.title);\n if (navIndex == -1)\n return false;\n \n if (contents[navIndex-1])\n {\n wikify("[[<< Previous|"+contents[navIndex-1]+"]]",place);\n place.lastChild.className += " navPrev";\n }\n if (contents[navIndex+1])\n {\n wikify("[[Next >>|"+contents[navIndex+1]+"]]",place);\n place.lastChild.className += " navNext";\n }\n\n var theTable = createTiddlyElement(place,"table",null,"nav");\n var theBody = createTiddlyElement(theTable,"tbody");\n var theRow = createTiddlyElement(theBody,"tr");\n for (var i=0; i<contents.length; i++)\n {\n var box = createTiddlyElement(theRow,"td",null,"navlinkcell"," ");\n box.onclick = onClickTiddlerLink;\n box.setAttribute("tiddlyLink",contents[i]);\n box.title = (contents[i]);\n if (contents[i] ==tiddler.title)\n box.className += " activenav";\n }\n}\n\nsetStylesheet(\n".navNext {float:right;}\sn"+\n".navPrev, .navPrevious{float:left;}\sn"+\n".nav .tiddlyLink {color:#000; background:transparent;border:none;padding:0;margin:0;}\sn"+\n".nav {padding:0;margin:0;}\sn"+\n".nav table {margin:0 auto !important; border:0px solid #000;padding:0;border-collapse:separate;}\sn"+\n".nav table tr{padding:0; margin:0;border-spacing: 1px;}\sn"+\n".nav table td {padding:4px; border:1px solid #000; border-spacing: 0px;cursor:pointer;cursor:hand}\sn"+\n".nav .activenav{background:#000 !important;}\sn","NavigationPluginStyles");
<!--{{{-->\n<div id="header" class='header'>\n <div class='gradient' macro='gradient vert #EF9934 #C86719 '>\n <div class='titleLine' >\n <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;\n <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>\n </div>\n\n </div>\n\n</div>\n<div id='bodywrapper'>\n\n<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>\n<div id='displayArea'>\n <div id='messageArea'></div>\n <div id='tiddlerDisplay'></div>\n</div>\n<div id='contentFooter' refresh='content' tiddler='contentFooter'></div>\n</div>
Tools
//{{{\nTiddlyWiki.prototype.removeNotification = function(title,fn) {\n for (var i=0;i<this.namedNotifications.length;i++)\n if((this.namedNotifications[i].name == title) && (this.namedNotifications[i].notify == fn))\n this.namedNotifications.splice(i,1);\n}\n \n//checks to see if a tiddler exists in store or as a shadow.\nTiddlyWiki.prototype.isTiddler= function (title)\n {return store.tiddlerExists(title) || store.isShadowTiddler(title)}\n\n// Refresh all tiddlers in the Story\nStory.prototype.lewcidrefreshAllTiddlers = function()\n{\n var place = document.getElementById(this.container);\n var e = place.firstChild;\n if(!e) return;\n this.refreshTiddler(e.getAttribute("tiddler"),null,true);\n while((e = e.nextSibling) != null)\n this.refreshTiddler(e.getAttribute("tiddler"),null,true);\n}\n\nconfig.presentationPlugin ={\n};\n\nconfig.presentationPlugin.defaults = [\n {name: "StyleSheet", notify: refreshStyles},\n {name: "PageTemplate", notify: refreshPageTemplate}\n ];\n\nwindow.presentationMode='';\n\nfunction applyPresentationMode (oldMode,Mode)\n{\n presentationMode = Mode;\n var defaults = config.presentationPlugin.defaults;\n var oldStyleElement = document.getElementById(oldMode+"StyleSheet");\n if (oldStyleElement)\n {\n oldStyleElement.parentNode.removeChild(oldStyleElement);\n }\n for (var i=0; i<defaults.length; i++)\n {\n var def = defaults[i]["name"];\n var newMode = store.isTiddler(Mode + def)? Mode + def : def;\n store.removeNotification(oldMode + def, defaults[i]["notify"]);\n store.addNotification(newMode,defaults[i]["notify"]);\n store.notify(newMode); //just one do blanket notify instead?\n }\n story.lewcidrefreshAllTiddlers();\n}\n\nconfig.macros.author={};\nconfig.macros.author.handler= function (place,macroName,params,wikifier,paramString,tiddler) {\n var e = createTiddlyElement(place,"div");\n e.setAttribute("refresh","macro");\n e.setAttribute("macroName","author");\n e.setAttribute("params",paramString);\n this.refresh(e,paramString);\n}\n\nconfig.macros.author.refresh = function(place,params){\n if (window.lewcideditmode== false)\n return false;\n removeChildren(place);\n var oldMode = window.presentationMode;\n var newMode = (oldMode == "Author")?"":"Author";\n var label = (oldMode == "Author")? "Presentation Mode":"Author Mode";\n var tooltip = label;\n createTiddlyButton(place,label,tooltip,function() {\n applyPresentationMode(oldMode,newMode);\n });\n};\n\nStory.prototype.chooseTemplateForTiddler_old_presentation = Story.prototype.chooseTemplateForTiddler;\n\nStory.prototype.chooseTemplateForTiddler = function(title,template)\n{\n if (!template)\n template = DEFAULT_VIEW_TEMPLATE;\n var mode = presentationMode;\n if (template == DEFAULT_VIEW_TEMPLATE)\n {\n if (store.isTiddler(mode+"ViewTemplate"))\n return mode+"ViewTemplate";\n }\n else if (template == DEFAULT_EDIT_TEMPLATE)\n {\n if (store.isTiddler(mode+"EditTemplate"))\n return mode+"EditTemplate";\n }\n return this.chooseTemplateForTiddler_old_presentation(title,template);\n}\n\nwindow.lewcideditmode = false;\nconfig.paramifiers.author = {\n onstart: function(v) {\n if (v!="true")\n return false;\n applyPresentationMode("","Author");\n window.lewcideditmode = true;\n if (config.options.chkSinglePageMode)\n config.options.chkSinglePageMode = false;\n refreshDisplay();\n }\n};\n//}}}
In Topofusion it is possible to easily reverse the direction of your track..\n\nfirst, make sure your track is all one track ..\n\nselect the 'profile and Playback' tool - hold down shift to select more segments of your track - make sure you start at the current start ..\n\nanyway .. rightclick on a segment and select reverse last segment -- really, make sure you have the whole stage as one track segment before you do this!!\n\nonce you have reversed your whole stage you can snip it to pieces and get on with your imports..
In Topofusion its possible to segment tracks and save the parts as separate files, this is especially handy if there are junctions on the stage, as they can get modeled more accurately as 2 tracks butting up against each other\n\nFirst, snip where the junction is using the scissors tool, now select the 'profile and Playback' tool ... click your segment, right click>save as - segment 1 or whatever\n\nRepeat at the next junction.\n\nDont forget to draw the part of the junction thats not on your stage .. this can make or break your attempts at reality ..\n\n
/***\n|''Name:''|SinglePageModePlugin|\n|''Source:''|http://www.TiddlyTools.com/#SinglePageModePlugin|\n|''Author:''|Eric Shulman - ELS Design Studios|\n|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|\n|''~CoreVersion:''|2.0.10|\n\nNormally, as you click on the links in TiddlyWiki, more and more tiddlers are displayed on the page. The order of this tiddler display depends upon when and where you have clicked. Some people like this non-linear method of reading the document, while others have reported that when many tiddlers have been opened, it can get somewhat confusing.\n\n!!!!!Usage\n<<<\nSinglePageMode allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one item displayed at a time. When SinglePageMode is enabled, the title of the current tiddler is automatically displayed in the browser window's titlebar and the browser's location URL is updated with a 'permalink' for the current tiddler so that it is easier to create a browser 'bookmark' for the current tiddler.\n\nEven when SinglePageMode is disabled (i.e., displaying multiple tiddlers is permitted), you can reduce the potential for confusion by enable TopOfPageMode, which forces tiddlers to always open at the top of the page instead of being displayed following the tiddler containing the link that was clicked.\n<<<\n!!!!!Configuration\n<<<\nWhen installed, this plugin automatically adds checkboxes in the AdvancedOptions tiddler so you can enable/disable the plugin behavior. For convenience, these checkboxes are also included here:\n\n<<option chkSinglePageMode>> Display one tiddler at a time\n<<option chkTopOfPageMode>> Always open tiddlers at the top of the page\n<<<\n!!!!!Installation\n<<<\nimport (or copy/paste) the following tiddlers into your document:\n''SinglePageModePlugin'' (tagged with <<tag systemConfig>>)\n^^documentation and javascript for SinglePageMode handling^^\n\nWhen installed, this plugin automatically adds checkboxes in the ''shadow'' AdvancedOptions tiddler so you can enable/disable this behavior. However, if you have customized your AdvancedOptions, you will need to ''manually add these checkboxes to your customized tiddler.''\n<<<\n!!!!!Revision History\n<<<\n''2006.07.04 [2.2.1]'' in hijack for displayTiddlers(), suspend TPM as well as SPM so that DefaultTiddlers displays in the correct order.\n''2006.06.01 [2.2.0]'' added chkTopOfPageMode (TPM) handling\n''2006.02.04 [2.1.1]'' moved global variable declarations to config.* to avoid FireFox 1.5.0.1 crash bug when assigning to globals\n''2005.12.27 [2.1.0]'' hijack displayTiddlers() so that SPM can be suspended during startup while displaying the DefaultTiddlers (or #hash list). Also, corrected initialization for undefined SPM flag to "false", so default behavior is to display multiple tiddlers\n''2005.12.27 [2.0.0]'' Update for TW2.0\n''2005.11.24 [1.1.2]'' When the back and forward buttons are used, the page now changes to match the URL. Based on code added by Clint Checketts\n''2005.10.14 [1.1.1]'' permalink creation now calls encodeTiddlyLink() to handle tiddler titles with spaces in them\n''2005.10.14 [1.1.0]'' added automatic setting of window title and location bar ('auto-permalink'). feature suggestion by David Dickens.\n''2005.10.09 [1.0.1]'' combined documentation and code in a single tiddler\n''2005.08.15 [1.0.0]'' Initial Release\n<<<\n!!!!!Credits\n<<<\nThis feature was developed by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]].\nSupport for BACK/FORWARD buttons adapted from code developed by Clint Checketts\n<<<\n!!!!!Code\n***/\n//{{{\nStory.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)\n{\n var place = document.getElementById(this.container);\n var theTiddler = document.getElementById(this.idPrefix + title);\n if(theTiddler)\n this.refreshTiddler(title,template);\n else\n {\n var before = this.positionTiddler(srcElement);\n theTiddler = this.createTiddler(place,before,title,template);\n }\n if(srcElement && typeof srcElement !== "string")\n {\n if(anim && config.options.chkAnimate && (animate == undefined || animate == true))\n anim.startAnimating(new Cascade(title,srcElement,theTiddler,slowly),new Scroller(theTiddler,slowly));\n else\n window.scrollTo(0,0);\n }\n}\n\n\n\nversion.extensions.SinglePageMode= {major: 2, minor: 2, revision: 1, date: new Date(2006,7,3)};\n\nconfig.options.chkSinglePageMode=true;\n\nif (config.options.chkSinglePageMode==undefined) config.options.chkSinglePageMode=false;\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkSinglePageMode>> Display one tiddler at a time";\n\nif (config.options.chkTopOfPageMode==undefined) config.options.chkTopOfPageMode=false;\nconfig.shadowTiddlers.AdvancedOptions += "\sn<<option chkTopOfPageMode>> Always open tiddlers at the top of the page";\n\nconfig.SPMTimer = 0;\nconfig.lastURL = window.location.hash;\nfunction checkLastURL()\n{\n if (!config.options.chkSinglePageMode)\n { window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }\n if (config.lastURL == window.location.hash)\n return;\n var tiddlerName = convertUTF8ToUnicode(decodeURI(window.location.hash.substr(1)));\n tiddlerName=tiddlerName.replace(/\s[\s[/,"").replace(/\s]\s]/,""); // strip any [[ ]] bracketing\n if (tiddlerName.length) story.displayTiddler(null,tiddlerName,1,null,null);\n}\n\nif (Story.prototype.SPM_coreDisplayTiddler==undefined) Story.prototype.SPM_coreDisplayTiddler=Story.prototype.displayTiddler;\nStory.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)\n{\n if (config.options.chkSinglePageMode) {\n window.location.hash = encodeURIComponent(String.encodeTiddlyLink(title));\n config.lastURL = window.location.hash;\n document.title = wikifyPlain("SiteTitle") + " - " + title;\n story.closeAllTiddlers();\n if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);\n }\n if (config.options.chkTopOfPageMode) { story.closeTiddler(title); window.scrollTo(0,0); srcElement=null; }\n this.SPM_coreDisplayTiddler(srcElement,title,template,animate,slowly)\n}\n\nif (Story.prototype.SPM_coreDisplayTiddlers==undefined) Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;\nStory.prototype.displayTiddlers = function(srcElement,titles,template,unused1,unused2,animate,slowly)\n{\n // suspend single-page mode when displaying multiple tiddlers\n var saveSPM=config.options.chkSinglePageMode; config.options.chkSinglePageMode=false;\n var saveTPM=config.options.chkTopOfPageMode; config.options.chkTopOfPageMode=false;\n this.SPM_coreDisplayTiddlers(srcElement,titles,template,unused1,unused2,animate,slowly);\n config.options.chkSinglePageMode=saveSPM; config.options.chkTopOfPageMode=saveTPM;\n}\n//}}}
A community supported site
Bob's Track Builder Tips
\n/***\nPlace your custom CSS here\n***/\n/*{{{*/\n\n\n[[SideBarWG]]\n\n/***\n!Top Menu Styles\n***/\n/*{{{*/\n#topMenu br {display:none; }\n#topMenu { background: #000 ; color:#fff;padding: 1em 1em;}\n/*}}}*/\n\n/***\n!General\n***/\n/*{{{*/\nbody {\n background: #444;\n margin: 0 auto;\n}\n\n #contentWrapper{\n background: #fff;\n border: 0;\n margin: 0 1em;\n\n padding:0;\n}\n/*}}}*/\n\n/***\n!Header rules\n***/\n/*{{{*/\n.titleLine{\n margin: 68px 3em 0em 0em;\nmargin-left:1.7em;\nmargin-bottom: 28px;\n padding: 0;\n text-align: left;\n color: #fff;\n}\n\n.siteTitle {\n font-size: 2em;\n font-weight: bold;\n}\n\n.siteSubtitle {\n font-size: 1.1em;\n display: block;\n margin: .5em auto 1em;\n}\n\n.gradient {margin: 0 auto; border-bottom:1px solid #000;}\n\n\n\n.header {\n background: #fff; \n margin: 0 0em;\n padding:0 12px;\n\n}\n/*}}}*/\n\n/***\n!Display Area\n***/\n/*{{{*/\n#bodywrapper {margin:0 12px; padding:0;background:#fff; height:1%}\n\n#displayArea{\n margin: 0em 16em 0em 14em;\n text-align: left;\n}\n\n.tiddler {\n padding: 1em 1em 0em 0em;\n}\n\nh1,h2,h3,h4,h5 { color: #000; background: transparent; padding-bottom:2px; border-bottom: 1px dotted #666; }\n.title {color:black; font-size:1.8em; border-bottom:1px solid #333; padding-bottom:0.3px;}\n.subtitle { font-size:90%; color:#ccc; padding-left:0.25em; margin-top:0.1em; }\n\n.shadow .title {\n color: #aaa;\n}\n\n.tagClear{\n clear: none; \n}\n\n* html .viewer pre {\n margin-left: 0em;\n}\n\n* html .editor textarea, * html .editor input {\n width: 98%;\n}\n\n.tiddler {margin-bottom:1em; padding-bottom:0em;}\n\n\n.toolbar .button {color:#bbb; border:none;}\n.toolbar .button:hover, .toolbar .highlight, .toolbar .marked, .toolbar a.button:active {background:transparent; color:#111; border:none; text-decoration:underline;}\n\n#sidebar .highlight, #sidebar .marked {background:transparent;}\n\n.tagging, .tagged {\n border: 1px solid #eee;\n background-color: #F7F7F7;\n}\n\n.selected .tagging, .selected .tagged {\n background-color: #eee;\n border: 1px solid #bbb;\n}\n\n .tagging .listTitle, .tagged .listTitle {\n color: #bbb;\n}\n\n.selected .tagging .listTitle, .selected .tagged .listTitle {\n color: #222; \n}\n\n\n.tagging .button:hover, .tagged .button:hover {\n border: none; background:transparent; text-decoration:underline; color:#000;\n}\n\n.tagging .button, .tagged .button {\n color:#aaa;\n}\n\n.selected .tagging .button, .selected .tagged .button {\n color:#000;\n}\n\n.viewer blockquote {\n border-left: 3px solid #000;\n}\n\n.viewer pre, .viewer code {\n border: 1px dashed #ccc;\n background: #eee;}\n\n.viewer hr {\n border: 0;\n border-top: solid 1px #333;\n margin: 0 8em;\n color: #333;\n}\n\n.highlight, .marked {background:transparent; color:#111; border:none; text-decoration:underline;}\n\n.viewer .highlight, .viewer .marked {text-decoration:none;}\n\n#sidebarTabs .highlight, #sidebarTabs .marked {color:#000; text-decoration:none;}\n\n.tabSelected {\n color: #000;\n background: #fff;\n border-top: solid 1px #ccc;\n border-left: solid 1px #ccc;\n border-right: solid 1px #ccc;\n border-bottom: none;\n}\n\n.viewer .tabSelected:hover{color:#000;}\n\n.viewer .tabSelected {font-weight:bold;}\n\n.tabUnselected {\n color: #999;\n background: #eee;\n border-top: solid 1px #ccc;\n border-left: solid 1px #ccc;\n border-right: solid 1px #ccc;\n border-bottom: solid 1px #ccc;\n padding-bottom:1px;\n}\n\n.tabContents {\n background: #fff;\n color: #000;\n}\n/*}}}*/\n/***\n!!!Tables\n***/\n/*{{{*/\n.viewer table {\n border: 1px solid #000;\n}\n\n.viewer th, thead td {\n background: #000;\n border: 1px solid #000;\n color: #fff;\n}\n\n.viewer td, .viewer tr {\n border: 1px solid #111; padding:4px;\n}\n/*}}}*/\n\n\n/***\n!!!Editor area\n***/\n/*{{{*/\n.editor input, .editor textarea {\n border: 1px solid #ccc;\n}\n\n.editor {padding-top:0.3em;}\n\n.editor textarea:focus, .editor input:focus {\n border: 1px solid #333;\n}\n/*}}}*/\n\n/***\n!Sidebar\n***/\n/*{{{*/\n#sidebar{\nposition:relative;\nfloat:right;\nmargin-bottom:1em;\ndisplay:inline;\nwidth: 16em;\n}\n\n#sidebarOptions .sliderPanel {\n background: #eee; border:1px solid #ccc;\n}\n\n/*}}}*/\n\n/***\n!Body Footer rules\n***/\n/*{{{*/\n#contentFooter {\n text-align: center;\n clear: both;\n color:#fff;\n background: #ccc;\n padding: 1em 2em;\nfont-weight:bold;\n}\n\n/*}}}*/\n/***\n!Link Styles\n***/\n/*{{{*/\na{\n color: #000;\n}\n\na:hover{\n color: #ED700B;\n background:#fff;\n}\n\n\n.button {\n color: #000;\n border: 1px solid #fff;\n}\n\n.button:hover {\n color: #fff;\n background: #ED700B;\n border-color: #000;\n}\n\n.button:active {\n color: #fff;\n background: #ED700B;\n border: 1px solid #000;\n}\n\n.tiddlyLink {border-bottom: 1px dotted #000;}\n.tiddlyLink:hover {border-bottom: 1px dotted #ED700B;} \n\n.titleLine a {border-bottom: 1px dotted #FF9900;}\n\n.titleLine a:hover {border-bottom: 1px dotted #fff;}\n\n.siteTitle a, .siteSubtitle a{\n color: #fff;\n}\n\n.viewer .button {border: 1px solid #ED700B; font-weight:bold;}\n.viewer .button:hover, .viewer .marked, .viewer .highlight{background:#ED700B; color:#fff; font-weight:bold; border: 1px solid #000;}\n\n#topMenu .button, #topMenu .tiddlyLink {\n margin-left:0.5em; margin-right:0.5em;\n padding-left:3px; padding-right:3px;\n color:white; font-weight:bold;\n}\n#topMenu .button:hover, #topMenu .tiddlyLink:hover { background:#000; color:#FF8814}\n\n#topMenu a{border:none;}\n/*}}}*/\n\n/***\n!Message Area /%=================================================%/\n***/\n/*{{{*/\n#messageArea {\n border: 4px dotted #ff8614;\n background: #000;\n color: #fff;\n font-size:90%;\n}\n\n#messageArea .button {\n padding: 0.2em;\n color: #000;\n background: #fff;\n text-decoration:none;\n font-weight:bold;\n border:1px solid #000; \n}\n\n#messageArea a {color:#fff;}\n\n#messageArea a:hover {color:#ff8614; background:transparent;}\n\n#messageArea .button:hover {background: #FF8614; color:#fff; border:1px solid #fff; }\n\n/*}}}*/\n\n/***\n!Popup /%=================================================%/\n***/\n/*{{{*/\n.popup {\n background: #ff8814;\n border: 1px solid #333;\n}\n\n.popup hr {\n color: #333;\n background: #333;\n border-bottom: 1px;\n}\n\n.popup li.disabled {\n color: #333;\n}\n\n.popup li a, .popup li a:visited {\n color: #eee;\n border: none;\n}\n\n.popup li a:hover {\n background: #ff8614;\n color: #fff;\n border: none;\n text-decoration:underline;\n}\n\n.searchBar {float:right; font-size:1em;}\n.searchBar .button {display:block; border:none; color:#ccc; }\n.searchBar .button:hover{border:none; color:#eee;}\n\n.searchBar input{\n border: 1px inset #000; background:#EFDFD1; width:10em; margin:0;\n}\n\n.searchBar input:focus {\n border: 1px inset #000; background:#fff;\n}\n\n*html .titleLine {margin-right:1.3em;}\n\n*html .searchBar .button {margin-left:1.7em;}\n\n .HideSideBarButton {float:right;} \n/*}}}*/\n\n.blog h2, .blog h3, .blog h4{\n margin:0;\n padding:0;\nborder-bottom:none;\n}\n.blog {margin-left:1.5em;} \n\n\n.blog .excerpt {\n margin:0;\nmargin-top:0.3em;\n padding: 0;\n margin-left:1em;\n padding-left:1em;\n font-size:90%;\n border-left:1px solid #ddd;\n}\n\n#tiddlerWhatsNew h1, #tiddlerWhatsNew h2 {border-bottom:none;}\ndiv[tags~="RecentUpdates"], div[tags~="lewcidExtension"] {margin-bottom: 2em;}\n\n#hoverMenu .button, #hoverMenu .tiddlyLink {border:none; font-weight:bold; background:#f37211; color:#fff; padding:0 5px; float:right; margin-bottom:4px;}\n#hoverMenu .button:hover, #hoverMenu .tiddlyLink:hover {font-weight:bold; border:none; color:#f37211; background:#000; padding:0 5px; float:right; margin-bottom:4px;}\n\n#topMenu .fontResizer {float:right;}\n\n#topMenu .fontResizer .button{border:1px solid #000;}\n#topMenu .fontResizer .button:hover {border:1px solid #f37211; color:#fff;}\n#sidebarTabs .txtMainTab .tiddlyLinkExisting {\n font-weight: normal;\n font-style: normal;\n}\n\n#sidebarTabs .txtMoreTab .tiddlyLinkExisting {\n font-weight: bold;\n font-style: normal;\n}\n\n\n\n\n\n#displayArea {margin-right:1em;}\n\n.headerShadow {\n position: relative;\n padding: 2.5em 0em 1em 1em;\n left: -1px;\n top: -1px;\n}\n\n.headerForeground {\n position: absolute;\n padding: 2.5em 0em 1em 1em;\n left: 0px;\n top: 0px;\n}\n\n.siteTitle {\n font-size: 2.5em;\n}\n\n.siteSubtitle {\n font-size: 1.2em;\n}\n\n#mainMenu {float:left; position:relative;}\n\n\n.viewer .button {border: 1px solid #ED700B; font-weight:bold;}\n.viewer .button:hover, .viewer .marked, .viewer .highlight{background:#ED700B; color:#fff; font-weight:bold; border: 1px solid #ED700B;}\n[[StyleSheetCommon]]\n#contentFooter .tiddlyLink {\n color:#fff;\n}\n/*}}}*/\n\n
.centre {text-align:center; margin:0;}\n.centre img {margin:0 auto;}\n\n.title, h1 {font-size: 1.6em; font-weight:bold; background:transparent; margin-top:0;margin-bottom:0; color:#000;}\n\nh2 {font-size: 1.45em; font-weight:bold; background:transparent; margin-top:0;margin-bottom:0; color:#000;}\n\n#mainMenu {width:14em;}\n#displayArea {margin-left:18em;}\n\n.left {float:left; margin-right:1em;}\n.bold {font-weight:bold;}\n\n\n\n.topbutton button, .topbutton{float:right;}\n\n.note{\n position:relative; /*this is the key*/\n z-index:24; background:#ccc;\n color:#000;\n text-decoration:none}\n\n.note:hover, .noteover{z-index:25; background-color:#FFB865;cursor:help;}\n\n.note span{display: none;}\n\n.note:hover span, .noteover span{ /*the span will display just on :hover state*/\n display:block;\n position:absolute;\n top:2em; left:2em; width:15em;\n border:1px solid #000;\n background-color:#FFB35A; color:#000;\n padding:0.5em;}\n\n\n\n.info{\n position:relative; /*this is the key*/\n z-index:24; background:#ccc;\n color:#000;\n text-decoration:none}\n\n.info:hover, .infoover{z-index:25; background-color:#FFB865;cursor:help;}\n\n.info span{display: none}\n\n.info:hover span, .infoover span{ /*the span will display just on :hover state*/\n display:block;\n position:absolute;\n top:2em; left:2em; width:15em;\n border:1px solid #000;\n background-color:#FFB35A; color:#000;\n padding:0.5em;}\n\n.bold {font-weight: bold !important;}
this guys working on 10 meter data hes acquiring from topo maps theres some great data here ...\nhttp://www.viewfinderpanoramas.org/dem3.html\n\nJust a few:\n\nFinland\nSweden\nNorway\nNorth of Italy - a few monte stages? For sure it looks like the col du turini is covered!!!\nhttp://perso.orange.fr/col-de-turini/en/turini/map.html\nparts of Greece\n\ncheck out the coverage:\n\nhttp://www.viewfinderpanoramas.org/coverage%20map%20viewfinderpanoramas_org3.htm\n\n\n3DEM - this handy program can create various types of DEMs [Digital Elevation Models] - you can create two useful file types - height maps, .jpg.bmp.tga etc.. which you can use with A.L.E. to create a .x mesh of your terrain. the other handy filtype is the ascii DEM - you use these 10m files to get better elevation data into your track in Topofusion\n\nhttp://www.ridgecrest.ca.us/~jslayton/wilbur.html\n\nhttp://plankgas.sprinterweb.net/tut.html -Track export tutorial\nhttp://plankgas.sprinterweb.net/exp.htm \n\nfree:\nhttp://www.viewfinderpanoramas.org/dem3.html - 10m DEM's outside the US\nhttp://www.viewfinderpanoramas.org/coverage%20map%20viewfinderpanoramas_org3.htm - coverage\n\nfree:\nhttp://www.visualizationsoftware.com/3dem.html - Create heightmaps from DEM files\n\nfree:\nhttp://www.ridgecrest.ca.us/~jslayton/wilbur.html manipulate and erode heightmaps, export .dxf among many other formats [get terrain into maxor whatever]\n\nfree unlimited demo:\nhttp://topofusion.com/3d.php#acquire - Acquiring DEM data\nhttp://topofusion.com/climb.php - use Heightmaps to add Elevation
Tiddler.prototype.getSubtitle = function()\n{\n return(this.title);\n}
free:\nhttp://www.viewfinderpanoramas.org/dem3.html - 10m DEM's outside the US\nhttp://www.viewfinderpanoramas.org/coverage%20map%20viewfinderpanoramas_org3.htm - coverage\n\nfree:\nhttp://www.visualizationsoftware.com/3dem.html - Create heightmaps from DEM files\n\nfree:\nhttp://www.ridgecrest.ca.us/~jslayton/wilbur.html manipulate and erode heightmaps, export .dxf among many other formats [get terrain into maxor whatever]\n\nfree unlimited demo:\nhttp://topofusion.com/3d.php#acquire - Acquiring DEM data\nhttp://topofusion.com/climb.php - use Heightmaps to add Elevation\n\nfree:\nhttp://www.gmap-pedometer.com/ - Draw .GPX files on google maps\n\nfree:\n.kml to .gpx converter [free]:\nhttp://bbs.keyhole.com/ubb/showthreaded.php/Cat/0/Number/101188/page/0\n\nfree:\nhttp://www.andytather.co.uk/Panda/directxmax_downloads.aspx\nand 3dsmax i guess for the finishing...\n\nhttp://plankgas.sprinterweb.net/tut.html -Track export tutorial\nhttp://plankgas.sprinterweb.net/exp.htm\n
config.macros.top={};\nconfig.macros.top.handler=function(place,macroName)\n{\n createTiddlyButton(place,"^","jump to top",this.onclick);\n}\nconfig.macros.top.onclick=function()\n{\n window.scrollTo(0,0);\n};
/***\nContains the stuff you need to use Tiddlyspot\nNote you must also have UploadPlugin installed\n***/\n//{{{\n\n// edit this if you are migrating sites or retrofitting an existing TW\nconfig.tiddlyspotSiteId = 'btb-tips';\n\n// make it so you can by default see edit controls via http\nconfig.options.chkHttpReadOnly = false;\nwindow.readOnly = false; // make sure of it (for tw 2.2)\n\n// disable autosave in d3\nif (window.location.protocol != "file:")\n config.options.chkGTDLazyAutoSave = false;\n\n// tweak shadow tiddlers to add upload button, password entry box etc\nwith (config.shadowTiddlers) {\n SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';\n SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");\n OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");\n DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[Welcome to Tiddlyspot]] ");\n MainMenu = MainMenu.replace(/^/,"[[Welcome to Tiddlyspot]] ");\n}\n\n// create some shadow tiddler content\nmerge(config.shadowTiddlers,{\n\n'Welcome to Tiddlyspot':[\n "This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //What now?// &nbsp;&nbsp;@@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",\n "<<tiddler TspotControls>>",\n "See also GettingStarted.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Working online// &nbsp;&nbsp;@@ You can edit this ~TiddlyWiki right now, and save your changes using the \s"save to web\s" button in the column on the right.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// &nbsp;&nbsp;@@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \s"upload\s" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Help!// &nbsp;&nbsp;@@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki Guides|http://tiddlywikiguides.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",\n "",\n "@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// &nbsp;&nbsp;@@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."\n].join("\sn"),\n\n'TspotControls':[\n "| tiddlyspot password:|<<option pasUploadPassword>>|",\n "| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<<br>>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",\n "| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[announcements|http://announce.tiddlyspot.com/]], [[blog|http://tiddlyspot.com/blog/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"\n].join("\sn"),\n\n'TspotSidebar':[\n "<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"\n].join("\sn"),\n\n'TspotOptions':[\n "tiddlyspot password:",\n "<<option pasUploadPassword>>",\n ""\n].join("\sn")\n\n});\n//}}}\n
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |\n| 14/6/2007 16:55:4 | YourName | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/6/2007 17:4:7 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#%5B%5BWelcome%20to%20Tiddlyspot%5D%5D]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:10:34 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:12:33 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:27:8 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:31:3 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:31:16 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:32:51 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:41:9 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:44:32 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 14/6/2007 17:49:7 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 14/6/2007 17:52:17 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . |\n| 15/6/2007 9:5:21 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 15/6/2007 9:13:43 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 15/6/2007 9:27:27 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . | Ok |\n| 15/6/2007 10:6:25 | AolBites | [[/|http://btb-tips.tiddlyspot.com/#author:true]] | [[store.cgi|http://btb-tips.tiddlyspot.com/store.cgi]] | . | index.html | . |
/***\n|''Name:''|UploadPlugin|\n|''Description:''|Save to web a TiddlyWiki|\n|''Version:''|3.4.5|\n|''Date:''|Oct 15, 2006|\n|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|\n|''Documentation:''|http://tiddlywiki.bidix.info/#UploadDoc|\n|''Author:''|BidiX (BidiX (at) bidix (dot) info)|\n|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|\n|''~CoreVersion:''|2.0.0|\n|''Browser:''|Firefox 1.5; InternetExplorer 6.0; Safari|\n|''Include:''|config.lib.file; config.lib.log; config.lib.options; PasswordTweak|\n|''Require:''|[[UploadService|http://tiddlywiki.bidix.info/#UploadService]]|\n***/\n//{{{\nversion.extensions.UploadPlugin = {\n major: 3, minor: 4, revision: 5, \n date: new Date(2006,9,15),\n source: 'http://tiddlywiki.bidix.info/#UploadPlugin',\n documentation: 'http://tiddlywiki.bidix.info/#UploadDoc',\n author: 'BidiX (BidiX (at) bidix (dot) info',\n license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',\n coreVersion: '2.0.0',\n browser: 'Firefox 1.5; InternetExplorer 6.0; Safari'\n};\n//}}}\n\n////+++!![config.lib.file]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.file) config.lib.file= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\nconfig.lib.file.dirname = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(0, lastpos);\n } else {\n return filePath.substring(0, filePath.lastIndexOf("\s\s"));\n }\n};\nconfig.lib.file.basename = function (filePath) {\n var lastpos;\n if ((lastpos = filePath.lastIndexOf("#")) != -1) \n filePath = filePath.substring(0, lastpos);\n if ((lastpos = filePath.lastIndexOf("/")) != -1) {\n return filePath.substring(lastpos + 1);\n } else\n return filePath.substring(filePath.lastIndexOf("\s\s")+1);\n};\nwindow.basename = function() {return "@@deprecated@@";};\n//}}}\n////===\n\n////+++!![config.lib.log]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.log) config.lib.log= {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 1}, \n date: new Date(2006,8,19)\n};\nconfig.lib.Log = function(tiddlerTitle, logHeader) {\n if (version.major < 2)\n this.tiddler = store.tiddlers[tiddlerTitle];\n else\n this.tiddler = store.getTiddler(tiddlerTitle);\n if (!this.tiddler) {\n this.tiddler = new Tiddler();\n this.tiddler.title = tiddlerTitle;\n this.tiddler.text = "| !date | !user | !location |" + logHeader;\n this.tiddler.created = new Date();\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[tiddlerTitle] = this.tiddler;\n else\n store.addTiddler(this.tiddler);\n }\n return this;\n};\n\nconfig.lib.Log.prototype.newLine = function (line) {\n var now = new Date();\n var newText = "| ";\n newText += now.getDate()+"/"+(now.getMonth()+1)+"/"+now.getFullYear() + " ";\n newText += now.getHours()+":"+now.getMinutes()+":"+now.getSeconds()+" | ";\n newText += config.options.txtUserName + " | ";\n var location = document.location.toString();\n var filename = config.lib.file.basename(location);\n if (!filename) filename = '/';\n newText += "[["+filename+"|"+location + "]] |";\n this.tiddler.text = this.tiddler.text + "\sn" + newText;\n this.addToLine(line);\n};\n\nconfig.lib.Log.prototype.addToLine = function (text) {\n this.tiddler.text = this.tiddler.text + text;\n this.tiddler.modifier = config.options.txtUserName;\n this.tiddler.modified = new Date();\n if (version.major < 2)\n store.tiddlers[this.tiddler.tittle] = this.tiddler;\n else {\n store.addTiddler(this.tiddler);\n story.refreshTiddler(this.tiddler.title);\n store.notify(this.tiddler.title, true);\n }\n if (version.major < 2)\n store.notifyAll(); \n};\n//}}}\n////===\n\n////+++!![config.lib.options]\n\n//{{{\nif (!config.lib) config.lib = {};\nif (!config.lib.options) config.lib.options = {\n author: 'BidiX',\n version: {major: 0, minor: 1, revision: 0}, \n date: new Date(2006,3,9)\n};\n\nconfig.lib.options.init = function (name, defaultValue) {\n if (!config.options[name]) {\n config.options[name] = defaultValue;\n saveOptionCookie(name);\n }\n};\n//}}}\n////===\n\n////+++!![PasswordTweak]\n\n//{{{\nversion.extensions.PasswordTweak = {\n major: 1, minor: 0, revision: 3, date: new Date(2006,8,30),\n type: 'tweak',\n source: 'http://tiddlywiki.bidix.info/#PasswordTweak'\n};\n//}}}\n/***\n!!config.macros.option\n***/\n//{{{\nconfig.macros.option.passwordCheckboxLabel = "Save this password on this computer";\nconfig.macros.option.passwordType = "password"; // password | text\n\nconfig.macros.option.onChangeOption = function(e)\n{\n var opt = this.getAttribute("option");\n var elementType,valueField;\n if(opt) {\n switch(opt.substr(0,3)) {\n case "txt":\n elementType = "input";\n valueField = "value";\n break;\n case "pas":\n elementType = "input";\n valueField = "value";\n break;\n case "chk":\n elementType = "input";\n valueField = "checked";\n break;\n }\n config.options[opt] = this[valueField];\n saveOptionCookie(opt);\n var nodes = document.getElementsByTagName(elementType);\n for(var t=0; t<nodes.length; t++) \n {\n var optNode = nodes[t].getAttribute("option");\n if (opt == optNode) \n nodes[t][valueField] = this[valueField];\n }\n }\n return(true);\n};\n\nconfig.macros.option.handler = function(place,macroName,params)\n{\n var opt = params[0];\n if(config.options[opt] === undefined) {\n return;}\n var c;\n switch(opt.substr(0,3)) {\n case "txt":\n c = document.createElement("input");\n c.onkeyup = this.onChangeOption;\n c.setAttribute ("option",opt);\n c.className = "txtOptionInput "+opt;\n place.appendChild(c);\n c.value = config.options[opt];\n break;\n case "pas":\n // input password\n c = document.createElement ("input");\n c.setAttribute("type",config.macros.option.passwordType);\n c.onkeyup = this.onChangeOption;\n c.setAttribute("option",opt);\n c.className = "pasOptionInput "+opt;\n place.appendChild(c);\n c.value = config.options[opt];\n // checkbox link with this password "save this password on this computer"\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option","chk"+opt);\n c.className = "chkOptionInput "+opt;\n place.appendChild(c);\n c.checked = config.options["chk"+opt];\n // text savePasswordCheckboxLabel\n place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));\n break;\n case "chk":\n c = document.createElement("input");\n c.setAttribute("type","checkbox");\n c.onclick = this.onChangeOption;\n c.setAttribute("option",opt);\n c.className = "chkOptionInput "+opt;\n place.appendChild(c);\n c.checked = config.options[opt];\n break;\n }\n};\n//}}}\n/***\n!! Option cookie stuff\n***/\n//{{{\nwindow.loadOptionsCookie_orig_PasswordTweak = window.loadOptionsCookie;\nwindow.loadOptionsCookie = function()\n{\n var cookies = document.cookie.split(";");\n for(var c=0; c<cookies.length; c++) {\n var p = cookies[c].indexOf("=");\n if(p != -1) {\n var name = cookies[c].substr(0,p).trim();\n var value = cookies[c].substr(p+1).trim();\n switch(name.substr(0,3)) {\n case "txt":\n config.options[name] = unescape(value);\n break;\n case "pas":\n config.options[name] = unescape(value);\n break;\n case "chk":\n config.options[name] = value == "true";\n break;\n }\n }\n }\n};\n\nwindow.saveOptionCookie_orig_PasswordTweak = window.saveOptionCookie;\nwindow.saveOptionCookie = function(name)\n{\n var c = name + "=";\n switch(name.substr(0,3)) {\n case "txt":\n c += escape(config.options[name].toString());\n break;\n case "chk":\n c += config.options[name] ? "true" : "false";\n // is there an option link with this chk ?\n if (config.options[name.substr(3)]) {\n saveOptionCookie(name.substr(3));\n }\n break;\n case "pas":\n if (config.options["chk"+name]) {\n c += escape(config.options[name].toString());\n } else {\n c += "";\n }\n break;\n }\n c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";\n document.cookie = c;\n};\n//}}}\n/***\n!! Initializations\n***/\n//{{{\n// define config.options.pasPassword\nif (!config.options.pasPassword) {\n config.options.pasPassword = 'defaultPassword';\n window.saveOptionCookie('pasPassword');\n}\n// since loadCookies is first called befor password definition\n// we need to reload cookies\nwindow.loadOptionsCookie();\n//}}}\n////===\n\n////+++!![config.macros.upload]\n\n//{{{\nconfig.macros.upload = {\n accessKey: "U",\n formName: "UploadPlugin",\n contentType: "text/html;charset=UTF-8",\n defaultStoreScript: "store.php"\n};\n\n// only this two configs need to be translated\nconfig.macros.upload.messages = {\n aboutToUpload: "About to upload TiddlyWiki to %0",\n backupFileStored: "Previous file backuped in %0",\n crossDomain: "Certainly a cross-domain isue: access to an other site isn't allowed",\n errorDownloading: "Error downloading",\n errorUploadingContent: "Error uploading content",\n fileLocked: "Files is locked: You are not allowed to Upload",\n fileNotFound: "file to upload not found",\n fileNotUploaded: "File %0 NOT uploaded",\n mainFileUploaded: "Main TiddlyWiki file uploaded to %0",\n passwordEmpty: "Unable to upload, your password is empty",\n urlParamMissing: "url param missing",\n rssFileNotUploaded: "RssFile %0 NOT uploaded",\n rssFileUploaded: "Rss File uploaded to %0"\n};\n\nconfig.macros.upload.label = {\n promptOption: "Save and Upload this TiddlyWiki with UploadOptions",\n promptParamMacro: "Save and Upload this TiddlyWiki in %0",\n saveLabel: "save to web", \n saveToDisk: "save to disk",\n uploadLabel: "upload" \n};\n\nconfig.macros.upload.handler = function(place,macroName,params){\n // parameters initialization\n var storeUrl = params[0];\n var toFilename = params[1];\n var backupDir = params[2];\n var uploadDir = params[3];\n var username = params[4];\n var password; // for security reason no password as macro parameter\n var label;\n if (document.location.toString().substr(0,4) == "http")\n label = this.label.saveLabel;\n else\n label = this.label.uploadLabel;\n var prompt;\n if (storeUrl) {\n prompt = this.label.promptParamMacro.toString().format([this.toDirUrl(storeUrl, uploadDir, username)]);\n }\n else {\n prompt = this.label.promptOption;\n }\n createTiddlyButton(place, label, prompt, \n function () {\n config.macros.upload.upload(storeUrl, toFilename, uploadDir, backupDir, username, password); \n return false;}, \n null, null, this.accessKey);\n};\nconfig.macros.upload.UploadLog = function() {\n return new config.lib.Log('UploadLog', " !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |" );\n};\nconfig.macros.upload.UploadLog.prototype = config.lib.Log.prototype;\nconfig.macros.upload.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {\n var line = " [[" + config.lib.file.basename(storeUrl) + "|" + storeUrl + "]] | ";\n line += uploadDir + " | " + toFilename + " | " + backupDir + " |";\n this.newLine(line);\n};\nconfig.macros.upload.UploadLog.prototype.endUpload = function() {\n this.addToLine(" Ok |");\n};\nconfig.macros.upload.basename = config.lib.file.basename;\nconfig.macros.upload.dirname = config.lib.file.dirname;\nconfig.macros.upload.toRootUrl = function (storeUrl, username)\n{\n return root = (this.dirname(storeUrl)?this.dirname(storeUrl):this.dirname(document.location.toString()));\n}\nconfig.macros.upload.toDirUrl = function (storeUrl, uploadDir, username)\n{\n var root = this.toRootUrl(storeUrl, username);\n if (uploadDir && uploadDir != '.')\n root = root + '/' + uploadDir;\n return root;\n}\nconfig.macros.upload.toFileUrl = function (storeUrl, toFilename, uploadDir, username)\n{\n return this.toDirUrl(storeUrl, uploadDir, username) + '/' + toFilename;\n}\nconfig.macros.upload.upload = function(storeUrl, toFilename, uploadDir, backupDir, username, password)\n{\n // parameters initialization\n storeUrl = (storeUrl ? storeUrl : config.options.txtUploadStoreUrl);\n toFilename = (toFilename ? toFilename : config.options.txtUploadFilename);\n backupDir = (backupDir ? backupDir : config.options.txtUploadBackupDir);\n uploadDir = (uploadDir ? uploadDir : config.options.txtUploadDir);\n username = (username ? username : config.options.txtUploadUserName);\n password = config.options.pasUploadPassword; // for security reason no password as macro parameter\n if (!password || password === '') {\n alert(config.macros.upload.messages.passwordEmpty);\n return;\n }\n if (storeUrl === '') {\n storeUrl = config.macros.upload.defaultStoreScript;\n }\n if (config.lib.file.dirname(storeUrl) === '') {\n storeUrl = config.lib.file.dirname(document.location.toString())+'/'+storeUrl;\n }\n if (toFilename === '') {\n toFilename = config.lib.file.basename(document.location.toString());\n }\n\n clearMessage();\n // only for forcing the message to display\n if (version.major < 2)\n store.notifyAll();\n if (!storeUrl) {\n alert(config.macros.upload.messages.urlParamMissing);\n return;\n }\n // Check that file is not locked\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n if (BidiX.GroupAuthoring.lock.isLocked() && !BidiX.GroupAuthoring.lock.isMyLock()) {\n alert(config.macros.upload.messages.fileLocked);\n return;\n }\n }\n \n var log = new this.UploadLog();\n log.startUpload(storeUrl, toFilename, uploadDir, backupDir);\n if (document.location.toString().substr(0,5) == "file:") {\n saveChanges();\n }\n var toDir = config.macros.upload.toDirUrl(storeUrl, toFilename, uploadDir, username);\n displayMessage(config.macros.upload.messages.aboutToUpload.format([toDir]), toDir);\n this.uploadChanges(storeUrl, toFilename, uploadDir, backupDir, username, password);\n if(config.options.chkGenerateAnRssFeed) {\n //var rssContent = convertUnicodeToUTF8(generateRss());\n var rssContent = generateRss();\n var rssPath = toFilename.substr(0,toFilename.lastIndexOf(".")) + ".xml";\n this.uploadContent(rssContent, storeUrl, rssPath, uploadDir, '', username, password, \n function (responseText) {\n if (responseText.substring(0,1) != '0') {\n displayMessage(config.macros.upload.messages.rssFileNotUploaded.format([rssPath]));\n }\n else {\n var toFileUrl = config.macros.upload.toFileUrl(storeUrl, rssPath, uploadDir, username);\n displayMessage(config.macros.upload.messages.rssFileUploaded.format(\n [toFileUrl]), toFileUrl);\n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n });\n }\n return;\n};\n\nconfig.macros.upload.uploadChanges = function(storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var original;\n if (document.location.toString().substr(0,4) == "http") {\n original = this.download(storeUrl, toFilename, uploadDir, backupDir, username, password);\n return;\n }\n else {\n // standard way : Local file\n \n original = loadFile(getLocalPath(document.location.toString()));\n if(window.Components) {\n // it's a mozilla browser\n try {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]\n .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);\n converter.charset = "UTF-8";\n original = converter.ConvertToUnicode(original);\n }\n catch(e) {\n }\n }\n }\n //DEBUG alert(original);\n this.uploadChangesFrom(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password);\n};\n\nconfig.macros.upload.uploadChangesFrom = function(original, storeUrl, toFilename, uploadDir, backupDir, \n username, password) {\n var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it\n var endSaveArea = '</d' + 'iv>';\n // Locate the storeArea div's\n var posOpeningDiv = original.indexOf(startSaveArea);\n var posClosingDiv = original.lastIndexOf(endSaveArea);\n if((posOpeningDiv == -1) || (posClosingDiv == -1))\n {\n alert(config.messages.invalidFileError.format([document.location.toString()]));\n return;\n }\n var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + \n allTiddlersAsHtml() + "\sn\st\st" +\n original.substr(posClosingDiv);\n var newSiteTitle;\n if(version.major < 2){\n newSiteTitle = (getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode();\n } else {\n newSiteTitle = (wikifyPlain ("SiteTitle") + " - " + wikifyPlain ("SiteSubtitle")).htmlEncode();\n }\n\n revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");\n revised = revised.replaceChunk("<!--PRE-HEAD-START--"+">","<!--PRE-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPreHead","") + "\sn");\n revised = revised.replaceChunk("<!--POST-HEAD-START--"+">","<!--POST-HEAD-END--"+">","\sn" + store.getTiddlerText("MarkupPostHead","") + "\sn");\n revised = revised.replaceChunk("<!--PRE-BODY-START--"+">","<!--PRE-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPreBody","") + "\sn");\n revised = revised.replaceChunk("<!--POST-BODY-START--"+">","<!--POST-BODY-END--"+">","\sn" + store.getTiddlerText("MarkupPostBody","") + "\sn");\n\n var response = this.uploadContent(revised, storeUrl, toFilename, uploadDir, backupDir, \n username, password, function (responseText) {\n if (responseText.substring(0,1) != '0') {\n alert(responseText);\n displayMessage(config.macros.upload.messages.fileNotUploaded.format([getLocalPath(document.location.toString())]));\n }\n else {\n if (uploadDir !== '') {\n toFilename = uploadDir + "/" + config.macros.upload.basename(toFilename);\n } else {\n toFilename = config.macros.upload.basename(toFilename);\n }\n var toFileUrl = config.macros.upload.toFileUrl(storeUrl, toFilename, uploadDir, username);\n if (responseText.indexOf("destfile:") > 0) {\n var destfile = responseText.substring(responseText.indexOf("destfile:")+9, \n responseText.indexOf("\sn", responseText.indexOf("destfile:")));\n toFileUrl = config.macros.upload.toRootUrl(storeUrl, username) + '/' + destfile;\n }\n else {\n toFileUrl = config.macros.upload.toFileUrl(storeUrl, toFilename, uploadDir, username);\n }\n displayMessage(config.macros.upload.messages.mainFileUploaded.format(\n [toFileUrl]), toFileUrl);\n if (backupDir && responseText.indexOf("backupfile:") > 0) {\n var backupFile = responseText.substring(responseText.indexOf("backupfile:")+11, \n responseText.indexOf("\sn", responseText.indexOf("backupfile:")));\n toBackupUrl = config.macros.upload.toRootUrl(storeUrl, username) + '/' + backupFile;\n displayMessage(config.macros.upload.messages.backupFileStored.format(\n [toBackupUrl]), toBackupUrl);\n }\n var log = new config.macros.upload.UploadLog();\n log.endUpload();\n store.setDirty(false);\n // erase local lock\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n BidiX.GroupAuthoring.lock.eraseLock();\n // change mtime with new mtime after upload\n var mtime = responseText.substr(responseText.indexOf("mtime:")+6);\n BidiX.GroupAuthoring.lock.mtime = mtime;\n }\n \n \n }\n // for debugging store.php uncomment last line\n //DEBUG alert(responseText);\n }\n );\n};\n\nconfig.macros.upload.uploadContent = function(content, storeUrl, toFilename, uploadDir, backupDir, \n username, password, callbackFn) {\n var boundary = "---------------------------"+"AaB03x"; \n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n if (window.netscape){\n try {\n if (document.location.toString().substr(0,4) != "http") {\n netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');}\n }\n catch (e) {}\n } \n //DEBUG alert("user["+config.options.txtUploadUserName+"] password[" + config.options.pasUploadPassword + "]");\n // compose headers data\n var sheader = "";\n sheader += "--" + boundary + "\sr\snContent-disposition: form-data; name=\s"";\n sheader += config.macros.upload.formName +"\s"\sr\sn\sr\sn";\n sheader += "backupDir="+backupDir\n +";user=" + username \n +";password=" + password\n +";uploaddir=" + uploadDir;\n // add lock attributes to sheader\n if (window.BidiX && BidiX.GroupAuthoring && BidiX.GroupAuthoring.lock) {\n var l = BidiX.GroupAuthoring.lock.myLock;\n sheader += ";lockuser=" + l.user\n + ";mtime=" + l.mtime\n + ";locktime=" + l.locktime;\n }\n sheader += ";;\sr\sn"; \n sheader += "\sr\sn" + "--" + boundary + "\sr\sn";\n sheader += "Content-disposition: form-data; name=\s"userfile\s"; filename=\s""+toFilename+"\s"\sr\sn";\n sheader += "Content-Type: " + config.macros.upload.contentType + "\sr\sn";\n sheader += "Content-Length: " + content.length + "\sr\sn\sr\sn";\n // compose trailer data\n var strailer = new String();\n strailer = "\sr\sn--" + boundary + "--\sr\sn";\n //strailer = "--" + boundary + "--\sr\sn";\n var data;\n data = sheader + content + strailer;\n //request.open("POST", storeUrl, true, username, password);\n try {\n request.open("POST", storeUrl, true); \n }\n catch(e) {\n alert(config.macros.upload.messages.crossDomain + "\snError:" +e);\n exit;\n }\n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if (request.status == 200)\n callbackFn(request.responseText);\n else\n alert(config.macros.upload.messages.errorUploadingContent + "\snStatus: "+request.status.statusText);\n }\n };\n request.setRequestHeader("Content-Length",data.length);\n request.setRequestHeader("Content-Type","multipart/form-data; boundary="+boundary);\n request.send(data); \n};\n\n\nconfig.macros.upload.download = function(uploadUrl, uploadToFilename, uploadDir, uploadBackupDir, \n username, password) {\n var request;\n try {\n request = new XMLHttpRequest();\n } \n catch (e) { \n request = new ActiveXObject("Msxml2.XMLHTTP"); \n }\n try {\n if (uploadUrl.substr(0,4) == "http") {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");\n }\n else {\n netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");\n }\n } catch (e) { }\n //request.open("GET", document.location.toString(), true, username, password);\n try {\n request.open("GET", document.location.toString(), true);\n }\n catch(e) {\n alert(config.macros.upload.messages.crossDomain + "\snError:" +e);\n exit;\n }\n \n request.onreadystatechange = function () {\n if (request.readyState == 4) {\n if(request.status == 200) {\n config.macros.upload.uploadChangesFrom(request.responseText, uploadUrl, \n uploadToFilename, uploadDir, uploadBackupDir, username, password);\n }\n else\n alert(config.macros.upload.messages.errorDownloading.format(\n [document.location.toString()]) + "\snStatus: "+request.status.statusText);\n }\n };\n request.send(null);\n};\n\n//}}}\n////===\n\n////+++!![Initializations]\n\n//{{{\nconfig.lib.options.init('txtUploadStoreUrl','store.php');\nconfig.lib.options.init('txtUploadFilename','');\nconfig.lib.options.init('txtUploadDir','');\nconfig.lib.options.init('txtUploadBackupDir','');\nconfig.lib.options.init('txtUploadUserName',config.options.txtUserName);\nconfig.lib.options.init('pasUploadPassword','');\nsetStylesheet(\n ".pasOptionInput {width: 11em;}\sn"+\n ".txtOptionInput.txtUploadStoreUrl {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadFilename {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadDir {width: 25em;}\sn"+\n ".txtOptionInput.txtUploadBackupDir {width: 25em;}\sn"+\n "",\n "UploadOptionsStyles");\nif (document.location.toString().substr(0,4) == "http") {\n config.options.chkAutoSave = false; \n saveOptionCookie('chkAutoSave');\n}\nconfig.shadowTiddlers.UploadDoc = "[[Full Documentation|http://tiddlywiki.bidix.info/l#UploadDoc ]]\sn"; \n\n//}}}\n////===\n\n////+++!![Core Hijacking]\n\n//{{{\nconfig.macros.saveChanges.label_orig_UploadPlugin = config.macros.saveChanges.label;\nconfig.macros.saveChanges.label = config.macros.upload.label.saveToDisk;\n\nconfig.macros.saveChanges.handler_orig_UploadPlugin = config.macros.saveChanges.handler;\n\nconfig.macros.saveChanges.handler = function(place)\n{\n if ((!readOnly) && (document.location.toString().substr(0,4) != "http"))\n createTiddlyButton(place,this.label,this.prompt,this.onClick,null,null,this.accessKey);\n};\n\n//}}}\n////===\n\n
<!--{{{-->\n<div class='viewer' macro='view text wikified'></div>\n<div class='viewer topbutton' macro='top'></div>\n<br><br>\n<div class='viewer' macro='navigation tiddlers:{{store.getTiddlerText("PresentationIndex").readBracketedList()}}}'></div>\n<div class='tagClear'></div>\n<!--}}}-->
The thread for this wiki\nhttp://www.bhmotorsports.com/board/viewtopic.php?t=43405 \n