diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bea18db93d8e53bff94ee97e417252802ec19a0f..40e757c738abe9872be1bde0c6dc5a2fc9208aef 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -8,6 +8,13 @@ set(CMAKE_C_FLAGS_RELEASE "-O3")
 set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") 
 
+if(WIN32)
+  add_definitions(-DWINDOWS)
+  if(MSVC)
+    # SSE2 optimizations
+    ADD_DEFINITIONS("/arch:SSE2")
+  endif()
+endif()
 
 #SET(CMAKE_BUILD_TYPE Debug)
 SET(CMAKE_BUILD_TYPE RelWithDebInfo)
diff --git a/src/csm/math_utils.cpp b/src/csm/math_utils.cpp
index ba7c6c8f5dc95e8680f70bd93adda8b4006ada77..30b5824be33b1b0c6ac5b837240e2dd5bacd5b1c 100644
--- a/src/csm/math_utils.cpp
+++ b/src/csm/math_utils.cpp
@@ -4,7 +4,7 @@
 #include "csm_all.h"
 
 int minmax(int from, int to, int x) {
-	return std::max(std::min(x,to),from);
+	return (std::max)((std::min)(x,to),from);
 }
 
 void possible_interval(
@@ -186,7 +186,7 @@ double dist_to_segment_d(const double a[2], const double b[2], const double x[2]
 		/* the projection is inside the segment */
 		return distance;
 	} else 
-		return sqrt(std::min( distance_squared_d(a,x), distance_squared_d(b,x)));
+		return sqrt((std::min)( distance_squared_d(a,x), distance_squared_d(b,x)));
 }
 
 int count_equal(const int*v, int n, int value) {
diff --git a/src/icp/icp_outliers.cpp b/src/icp/icp_outliers.cpp
index 7c2e32a8c92721f76fee803a9b8c41a523f03bb6..bc68babfa92141ca946969dd8a45e64dd70005cc 100644
--- a/src/icp/icp_outliers.cpp
+++ b/src/icp/icp_outliers.cpp
@@ -59,7 +59,7 @@ void kill_outliers_double(struct sm_params*params) {
 		if(!ld_valid_corr(laser_sens, i)) continue;
 		int j1 = laser_sens->corr[i].j1;
 		dist2_i[i] = laser_sens->corr[i].dist2_j1;
-		dist2_j[j1] = std::min(dist2_j[j1], dist2_i[i]);
+		dist2_j[j1] = (std::min)(dist2_j[j1], dist2_i[i]);
 	}
 	
 	int nkilled = 0;
@@ -121,7 +121,7 @@ void kill_outliers_trim(struct sm_params*params,  double*total_error) {
 	/* two errors limits are defined: */
 		/* In any case, we don't want more than outliers_maxPerc% */
 		int order = (int)floor(k*(params->outliers_maxPerc));
-			order = std::max(0, std::min(order, k-1));
+			order = (std::max)(0, (std::min)(order, k-1));
 
 	/* The dists for the correspondence are sorted
 	   in ascending order */
@@ -131,10 +131,10 @@ void kill_outliers_trim(struct sm_params*params,  double*total_error) {
 		/* Then we take a order statics (o*K) */
 		/* And we say that the error must be less than alpha*dist(o*K) */
 		int order2 = (int)floor(k*params->outliers_adaptive_order);
-			order2 = std::max(0, std::min(order2, k-1));
+			order2 = (std::max)(0, (std::min)(order2, k-1));
 		double error_limit2 = params->outliers_adaptive_mult*dist2[order2];
 	
-	double error_limit = std::min(error_limit1, error_limit2);
+	double error_limit = (std::min)(error_limit1, error_limit2);
 	
 #if 0
 	double error_limit1_ho = hoare_selection(dist2_copy, 0, k-1, order);